Пример #1
0
        public async Task RtpStream(string rtpurl, CancellationToken cancellationToken)
        {
            this.Response.StatusCode = 200;
            this.Response.Headers.Add(HeaderNames.ContentDisposition, $"attachment; filename=\"stream\"");
            this.Response.Headers.Add(HeaderNames.ContentType, "application/octet-stream");
            var pipe = new StreamPipeSink(this.Response.Body);
            var arg  = FFMpegCore.FFMpegArguments.FromFileInput($"rtp://{rtpurl}", false).OutputToPipe(pipe, options =>

            {
                options.ForceFormat("mpegts");
                options.WithAudioCodec("aac");
                options.WithVideoCodec("copy");
                options.WithFastStart();
                options.UsingMultithreading(true);
                options.WithCustomArgument("-analyzeduration 500000");
                options.WithCustomArgument("-fflags nobuffer");
                options.WithCustomArgument("-flags low_delay");
                options.WithCustomArgument("-max_delay 250000");
                options.WithCustomArgument("-max_interleave_delta 1"); // see https://github.com/l3tnun/EPGStation/issues/433
            });

            arg.CancellableThrough(out var cancel);
            cancellationToken.Register(cancel);
            await arg.ProcessAsynchronously();
        }
Пример #2
0
        public static Stream ConvertToWav(Stream inputStream, string mimeType)
        {
            if (mimeType.EndsWith("/wav"))
            {
                return(inputStream);
            }

            var outputStream = new MemoryStream();
            var outputPipe   = new StreamPipeSink(outputStream);

            outputPipe.Format = "wav";

            // pcm_s16le or pcm_s32le
            var ffargs = FFMpegArguments
                         .FromPipeInput(new StreamPipeSource(inputStream))
                         .OutputToPipe(outputPipe,
                                       options => options.WithCustomArgument("-ar 8000 -c:a pcm_s16le")
                                       .ForceFormat("wav")
                                       );

            ffargs.ProcessAsynchronously().Wait();


            return(outputStream);
        }
Пример #3
0
        // Old solution using FFmpeg
        public void GetColors(Action <Color4[]> callback, int time)
        {
            Task.Run(() =>
            {
                if (videoFile == null)
                {
                    return;
                }

                Stream stream;

                var sink = new StreamPipeSink(stream = new MemoryStream());

                var path = store.Storage.GetFullPath(videoFile);

                FFMpegArguments
                .FromFileInput(path, true, opt =>
                               opt.Seek(TimeSpan.FromMilliseconds(time)))
                .OutputToPipe(sink, opt =>
                              opt.WithFrameOutputCount(1)
                              .WithArgument(new CustomArgument("-s 16x16"))
                              .ForceFormat("image2"))
                .ProcessSynchronously();

                stream.Seek(0, SeekOrigin.Begin);

                using Image <Rgb24> image = SixLabors.ImageSharp.Image.Load <Rgb24>(stream);

                callback(getImageColors(image));
            });
        }
Пример #4
0
        public async Task Produce(IBoundedQueue <MutableByteImage> sourceQueue)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(_arguments.PathToFfmpeg))
                {
                    FFMpegOptions.Configure(new FFMpegOptions
                    {
                        RootDirectory = _arguments.PathToFfmpeg
                    });
                }

                var result = await FFProbe.AnalyseAsync(_arguments.InputFile).ConfigureAwait(false);

                var width          = result.PrimaryVideoStream.Width;
                var height         = result.PrimaryVideoStream.Height;
                var bpp            = Image.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format24bppRgb) / 8;
                var pixelsPerFrame = width * height;

                var frameSizeInBytes = pixelsPerFrame * bpp;

                _logger.WriteLine("Input from ffmpeg currently only supports rgb24-convertable input", Verbosity.Warning);

                var chunksQueue = BoundedQueueFactory.Get <byte[]>(4, "In-ChuQ");
                using var memoryStream = new ChunkedSimpleMemoryStream(frameSizeInBytes, chunksQueue); // new MemoryStream(frameSizeInBytes);
                StreamPipeSink sink = new StreamPipeSink(memoryStream);
                var            args = FFMpegArguments
                                      .FromFileInput(_arguments.InputFile).OutputToPipe(sink, options =>
                                                                                        options.DisableChannel(FFMpegCore.Enums.Channel.Audio)
                                                                                        .UsingMultithreading(true)
                                                                                        .ForceFormat("rawvideo")
                                                                                        .WithCustomArgument(_arguments.CustomArgs ?? string.Empty)
                                                                                        .ForcePixelFormat("bgr24"))
                                      .NotifyOnProgress(
                    percent => _logger.NotifyFillstate(Convert.ToInt32(percent), "InputVideoParsing"),
                    TimeSpan.FromSeconds(1));

                var produceTask = args.ProcessAsynchronously(true).ContinueWith((_) =>
                {
                    chunksQueue.CompleteAdding();
                    sourceQueue.CompleteAdding();
                });
                var consumeTask = ParseInputStream(sourceQueue, chunksQueue, width, height, memoryStream)
                                  .ContinueWith((_) => _logger.WriteLine("finished reading", Verbosity.Info));

                await Task.WhenAll(produceTask, consumeTask);

                _logger.WriteLine("finished reading", Verbosity.Info);
            }
            catch (System.ComponentModel.Win32Exception)
            {
                _logger.WriteLine("Couldn't find ffmpeg", Verbosity.Error);
            }
            catch (Exception e)
            {
                _logger.LogException(e);
            }
        }
Пример #5
0
 public async Task Video_ToMP4_Args_StreamOutputPipe_Async()
 {
     await using var ms = new MemoryStream();
     var pipeSource = new StreamPipeSink(ms);
     await FFMpegArguments
     .FromFileInput(TestResources.Mp4Video)
     .OutputToPipe(pipeSource, opt => opt
                   .WithVideoCodec(VideoCodec.LibX264)
                   .ForceFormat("matroska"))
     .ProcessAsynchronously();
 }
Пример #6
0
 public async Task Video_ToMP4_Args_StreamOutputPipe_Async_Failure()
 {
     await Assert.ThrowsExceptionAsync <FFMpegException>(async() =>
     {
         await using var ms = new MemoryStream();
         var pipeSource     = new StreamPipeSink(ms);
         await FFMpegArguments
         .FromFileInput(TestResources.Mp4Video)
         .OutputToPipe(pipeSource, opt => opt.ForceFormat("mkv"))
         .ProcessAsynchronously();
     });
 }
Пример #7
0
        public void Video_ToMP4_Args_StreamOutputPipe_Async()
        {
            using var ms = new MemoryStream();
            var pipeSource = new StreamPipeSink(ms);

            FFMpegArguments
            .FromFileInput(VideoLibrary.LocalVideo)
            .OutputToPipe(pipeSource, opt => opt
                          .WithVideoCodec(VideoCodec.LibX264)
                          .ForceFormat("matroska"))
            .ProcessAsynchronously()
            .WaitForResult();
        }
Пример #8
0
 // [TestMethod, Timeout(10000)]
 public async Task Video_ToMP4_Args_StreamOutputPipe_Async_Failure()
 {
     await Assert.ThrowsExceptionAsync <FFMpegException>(async() =>
     {
         await using var ms = new MemoryStream();
         var pipeSource     = new StreamPipeSink(ms);
         await FFMpegArguments
         .FromInputFiles(VideoLibrary.LocalVideo)
         .ForceFormat("mkv")
         .OutputToPipe(pipeSource)
         .ProcessAsynchronously();
     });
 }
Пример #9
0
        private void ConvertToStreamPipe(params IArgument[] inputArguments)
        {
            using var ms = new MemoryStream();
            var arguments = FFMpegArguments.FromInputFiles(VideoLibrary.LocalVideo);

            foreach (var arg in inputArguments)
            {
                arguments.WithArgument(arg);
            }

            var streamPipeDataReader = new StreamPipeSink(ms);
            var processor            = arguments.OutputToPipe(streamPipeDataReader);

            var scaling = arguments.Find <ScaleArgument>();

            processor.ProcessSynchronously();

            ms.Position = 0;
            var outputVideo = FFProbe.Analyse(ms);

            var input = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName);

            // Assert.IsTrue(Math.Abs((outputVideo.Duration - input.Duration).TotalMilliseconds) < 1000.0 / input.PrimaryVideoStream.FrameRate);

            if (scaling?.Size == null)
            {
                Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
                Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
            }
            else
            {
                if (scaling.Size.Value.Width != -1)
                {
                    Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width);
                }

                if (scaling.Size.Value.Height != -1)
                {
                    Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height);
                }

                Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
                Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
            }
        }
Пример #10
0
        public void Video_TranscodeInMemory()
        {
            using var resStream = new MemoryStream();
            var reader = new StreamPipeSink(resStream);
            var writer = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 128, 128));

            FFMpegArguments
            .FromPipeInput(writer)
            .OutputToPipe(reader, opt => opt
                          .WithVideoCodec("vp9")
                          .ForceFormat("webm"))
            .ProcessSynchronously();

            resStream.Position = 0;
            var vi = FFProbe.Analyse(resStream);

            Assert.AreEqual(vi.PrimaryVideoStream.Width, 128);
            Assert.AreEqual(vi.PrimaryVideoStream.Height, 128);
        }
Пример #11
0
        public async Task Video_Cancel_Async()
        {
            await using var resStream = new MemoryStream();
            var reader = new StreamPipeSink(resStream);
            var writer = new RawVideoPipeSource(BitmapSource.CreateBitmaps(512, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 128, 128));

            var task = FFMpegArguments
                       .FromPipe(writer)
                       .WithVideoCodec("vp9")
                       .ForceFormat("webm")
                       .OutputToPipe(reader)
                       .CancellableThrough(out var cancel)
                       .ProcessAsynchronously(false);

            await Task.Delay(300);

            cancel();

            var result = await task;

            Assert.IsFalse(result);
        }
        public async Task Produce(ConcurrentQueue <MutableByteImage> queue)
        {
            try
            {
                FFMpegOptions.Configure(new FFMpegOptions
                {
                    RootDirectory = _arguments.PathToFfmpeg
                });

                var result = await FFProbe.AnalyseAsync(_arguments.InputFiles.First()).ConfigureAwait(false);

                var width          = result.PrimaryVideoStream.Width;
                var height         = result.PrimaryVideoStream.Height;
                var bpp            = Image.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format24bppRgb) / 8;
                var pixelsPerFrame = width * height;

                var frameSizeInBytes = pixelsPerFrame * bpp;

                _logger.WriteLine("Input from ffmpeg currently only supports rgb24-convertable input", Verbosity.Warning);

                var chunksQueue = new ConcurrentQueue <byte[]>();
                using var memoryStream = new ChunkedMemoryStream(frameSizeInBytes, chunksQueue); // new MemoryStream(frameSizeInBytes);
                StreamPipeSink sink = new StreamPipeSink(memoryStream);
                var            args = FFMpegArguments
                                      .FromInputFiles(_arguments.InputFiles)
                                      .UsingMultithreading(true)
                                      .ForceFormat("rawvideo")
                                      .ForcePixelFormat("bgr24")
                                      .OutputToPipe(sink)
                                      .NotifyOnProgress(
                    percent => _logger.NotifyFillstate(Convert.ToInt32(percent), "InputVideoParsing"),
                    TimeSpan.FromSeconds(1));

                var produceTask = args.ProcessAsynchronously(true).ContinueWith((_) => parsingFinished.Cancel());
                var consumeTask = ParseInputStream(queue, chunksQueue, width, height, frameSizeInBytes, memoryStream);

                await Task.WhenAll(produceTask, consumeTask);

                //    await Task.WhenAny(produceTask, consumeTask).ConfigureAwait(false);
            }
            catch (Exception e)
            {
            }

            async Task ParseInputStream(ConcurrentQueue <MutableByteImage> queue, ConcurrentQueue <byte[]> chunksQueue, int width, int height, int frameSizeInBytes, ChunkedMemoryStream memoryStream)
            {
                int count = 0;

                while (true)
                //while ((memoryStream.HasUnwrittenData || chunksQueue.Count > 0) && !parsingFinished.IsCancellationRequested)
                {
                    try
                    {
                        var foo = await chunksQueue.TryDequeueOrWait(parsingFinished);

                        if (foo.cancelled)
                        {
                            break;
                        }
                        _logger.NotifyFillstate(++count, "ParsedImages");
                        _logger.NotifyFillstate(chunksQueue.Count, "ChunkedQueue");
                        queue.Enqueue(_factory.FromBytes(width, height, foo.item));
                    }
                    catch (Exception e) { _logger.LogException(e); }

                    await queue.WaitForBufferSpace(24);
                }
                Console.WriteLine(memoryStream.HasUnwrittenData);
            }
        }