Esempio n. 1
0
        private async void Transcode(Movie movie, Transcode transcodeProfile, Server server, string callbackUrl)
        {
            var client = new SshClient(server.Ip, "root", server.RootPassword);

            try
            {
                string successCallbackUrl = callbackUrl.Replace("STATE", StreamState.Ready.ToString());
                var    options            = new Dictionary <string, string>
                {
                    { "hls_time", "4" },
                    { "hls_playlist_type", "vod" }
                };
                string transcoder     = FFMPEGCommand.MakeCommand(transcodeProfile, movie.Source, $"/var/hls/{movie.StreamKey}", options);
                string prepareCommand = $"mkdir /var/hls/{movie.StreamKey}";
                prepareCommand += $" && cd /var/hls/{movie.StreamKey}";
                prepareCommand += $" && mkdir 1080p 720p 480p 360p";

                client.Connect();
                client.RunCommand(prepareCommand);
                var cmd    = client.CreateCommand($"nohup sh -c '{transcoder} && curl -i -X GET {successCallbackUrl}' >/dev/null 2>&1 & echo $!");
                var result = cmd.Execute();
                int pid    = int.Parse(result);
                client.RunCommand($"disown -h {pid}");
                client.Disconnect();
                client.Dispose();
            }
            catch (Exception)
            {
                string failCallbackUrl = callbackUrl.Replace("STATE", StreamState.Error.ToString());
                var    httpClient      = new HttpClient();
                await httpClient.GetAsync(failCallbackUrl);
            }
        }
        public async Task <IActionResult> Edit(int id)
        {
            var channel = await channelRepository.GetById(id, new string[] { "ChannelServers" });

            if (channel != null)
            {
                if (channel.SourceTranscodedCount < channel.SourceCount)
                {
                    channel.SourceTranscodedCount++;
                }

                if (channel.SourceCount == channel.SourceTranscodedCount)
                {
                    var server = await serverRepository.GetById(channel.ChannelServers.FirstOrDefault().ServerId);

                    ThreadPool.QueueUserWorkItem(queue => {
                        try
                        {
                            string input              = $"/var/hls/{channel.StreamKey}/sources/RESOLUTION/source_list.txt";
                            string output             = $"/var/hls/{channel.StreamKey}";
                            List <string> transcoders = FFMPEGCommand.ChannelCommand(input, output);
                            var client = new SshClient(server.Ip, "root", server.RootPassword);
                            client.Connect();

                            foreach (var transcoder in transcoders)
                            {
                                var cmd    = client.CreateCommand($"nohup {transcoder} >/dev/null 2>&1 & echo $!");
                                var result = cmd.Execute();
                                int pid    = int.Parse(result);
                                client.RunCommand($"disown -h {pid}");
                            }

                            client.Disconnect();
                            client.Dispose();
                        }
                        catch
                        {
                        }
                    });
                    channel.State = StreamState.Live;
                    await hub.Clients.All.SendAsync("UpdateSignal", new { id, state = (int)StreamState.Live });
                }

                await channelRepository.Edit(channel);
            }

            return(Ok());
        }
Esempio n. 3
0
        public async Task Update(int sourceId, StreamState state)
        {
            var stream = await streamRepository.GetById(sourceId, new string[] { "StreamServers", "StreamServers.Server", "Transcode" });

            if (stream == null)
            {
                return;
            }

            if (stream.State == state)
            {
                return;
            }

            if (state == StreamState.Live)
            {
                var options = new Dictionary <string, string>
                {
                    { "hls_time", "4" },
                    { "hls_playlist_type", "event" }
                };
                if (!stream.Record)
                {
                    options.Add("hls_flags", "delete_segments");
                }
                string transcode      = FFMPEGCommand.MakeCommand(stream.Transcode, stream.Source, $"/var/hls/{stream.StreamKey}", options);
                string prepareCommand = $"mkdir /var/hls/{stream.StreamKey}";
                prepareCommand      += $" && cd /var/hls/{stream.StreamKey}";
                prepareCommand      += $" && mkdir 1080p 720p 480p 360p";
                stream.StreamServers = (List <StreamServer>)Start((IList <StreamServer>)stream.StreamServers, prepareCommand, transcode);
            }
            else if (state == StreamState.Stopped)
            {
                string prepareCommand = $"rm -rf /var/hls/{stream.StreamKey}";
                stream.StreamServers = (List <StreamServer>)Stop((IList <StreamServer>)stream.StreamServers, prepareCommand);
            }

            stream.State = state;
            await streamRepository.Edit(stream);

            await Clients.All.SendAsync("Update", new { sourceId, state = (int)state });
        }
Esempio n. 4
0
        private async void Transcode(Channel channel, Transcode transcodeProfile, Server server, string callbackUrl)
        {
            var client = new SshClient(server.Ip, "root", server.RootPassword);

            try
            {
                string   successCallbackUrl = callbackUrl.Replace("/STATE", string.Empty);
                string   streamDirectory    = $"/var/hls/{channel.StreamKey}";
                string   prepareCommand     = $"mkdir {streamDirectory}";
                string[] resolutions        = new string[]
                {
                    "1080p",
                    "720p",
                    "480p",
                    "360p"
                };

                prepareCommand += $" && cd {streamDirectory}";
                prepareCommand += " && mkdir 1080p 720p 480p 360p sources";
                prepareCommand += " && cd sources";
                prepareCommand += " && mkdir 1080p 720p 480p 360p";

                foreach (string resolution in resolutions)
                {
                    StringBuilder sourceList = new StringBuilder();

                    for (int i = 0; i < channel.SourcePath.Length; i++)
                    {
                        sourceList.Append($"file '{streamDirectory}/sources/{resolution}/{i}.ts'\n");
                    }

                    prepareCommand += $" && printf \"{sourceList}\" > {streamDirectory}/sources/{resolution}/source_list.txt";
                }

                client.Connect();
                client.RunCommand(prepareCommand);

                for (int i = 0; i < channel.SourcePath.Length; i++)
                {
                    var options = new Dictionary <string, string>
                    {
                        { "custom_output", string.Empty },
                        { "custom_output_1080p", $"{streamDirectory}/sources/1080p/{i}.ts" },
                        { "custom_output_720p", $"{streamDirectory}/sources/720p/{i}.ts" },
                        { "custom_output_480p", $"{streamDirectory}/sources/480p/{i}.ts" },
                        { "custom_output_360p", $"{streamDirectory}/sources/360p/{i}.ts" }
                    };
                    string transcoder = FFMPEGCommand.MakeCommand(transcodeProfile, channel.SourcePath[i], string.Empty, options);
                    var    cmd        = client.CreateCommand($"nohup sh -c '{transcoder} && curl -i -X GET {successCallbackUrl}' >/dev/null 2>&1 & echo $!");
                    var    result     = cmd.Execute();
                    int    pid        = int.Parse(result);
                    client.RunCommand($"disown -h {pid}");
                }

                client.Disconnect();
                client.Dispose();
            }
            catch (Exception)
            {
                string failCallbackUrl = callbackUrl.Replace("STATE", StreamState.Error.ToString());
                var    httpClient      = new HttpClient();
                await httpClient.GetAsync(failCallbackUrl);
            }
        }
Esempio n. 5
0
 public CommandBase(string executePath)
 {
     FFMPEGCommand = new FFMPEGCommand(executePath);
 }
        public string WritePart()
        {
            FFMPEGCommand.AddInput(VideoPath);
            FFMPEGCommand.AddInput(AudioPath);

            /*
             * FFMPEGCommand.AddFlag(new SimpleFlag("filter_complex", "[0:a][1:a]amix=duration=first[aout]"));
             */

            FilterComplexExpression fadeExpression = new FilterComplexExpression()
                                                     .AddInputIdentifier("1:a")
                                                     .AddFilter(new Filter()
                                                                .SetName("volume")
                                                                .SetValue(AudioVolume.ToString()))
                                                     .AddFilter(new Filter()
                                                                .SetName("afade")
                                                                .AddAttribute("t", "in")
                                                                .AddAttribute("st", "0")
                                                                .AddAttribute("d", AudioFadeDuration.ToString()))
                                                     .AddFilter(new Filter()
                                                                .SetName("afade")
                                                                .AddAttribute("t", "out")
                                                                .AddAttribute("st", (VideoDuration - AudioFadeDuration).ToString())
                                                                .AddAttribute("d", AudioFadeDuration.ToString()))
                                                     .SetOutputIdentifier("afaded");

            FilterComplexExpression mixExpression = new FilterComplexExpression()
                                                    .AddInputIdentifier("0:a")
                                                    .AddInputIdentifier("afaded")
                                                    .AddFilter(new Filter()
                                                               .SetName("amix")
                                                               .AddAttribute("duration", "first"))
                                                    .SetOutputIdentifier("acompressed");

            /* Audio Compressor.
             */
            FilterComplexExpression compressorExpression = new FilterComplexExpression()
                                                           .AddInputIdentifier("acompressed")
                                                           .AddFilter(new Filter()
                                                                      .SetName("acompressor")
                                                                      .AddAttribute("threshold", Threshold.ToString())
                                                                      .AddAttribute("ratio", Ratio)
                                                                      .AddAttribute("attack", Attack.ToString())
                                                                      .AddAttribute("release", Release.ToString())
                                                                      .AddAttribute("makeup", MakeupGain.ToString()))
                                                           .SetOutputIdentifier("aout");


            FilterComplexFlag fcf = new FilterComplexFlag()
                                    .AddFilterComplexExpression(fadeExpression)
                                    .AddFilterComplexExpression(mixExpression)
                                    .AddFilterComplexExpression(compressorExpression);

            FFMPEGCommand.AddFlag(fcf);
            FFMPEGCommand.AddFlag(new SimpleFlag("map", "0:v"));
            FFMPEGCommand.AddFlag(new SimpleFlag("map", "[aout]"));

            FFMPEGCommand.AddFlag(new SimpleFlag("c:v", "copy"));

            FFMPEGCommand.AddFlag(new SimpleFlag("y", null));

            return(FFMPEGCommand.WritePart());
        }
 public MixAudioIntoVideoCommand SetOutput(string output)
 {
     FFMPEGCommand.SetOutput(output);
     return(this);
 }