Exemple #1
0
 public Stream ReadVideoFrame(TimeSpan seek, Size?size)
 {
     this.Dispose();
     try
     {
         FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();
         fFmpegArgsBuilder.GlobalOptionArgs
         .SetThreadQueueSize(512)
         ;
         fFmpegArgsBuilder.SetInputFile(this.filePath)
         .SeekAccurate()
         .ReadByNativeFrame()
         .SetSeek(seek)
         ;
         var outputOptionArgs = fFmpegArgsBuilder.SetOutputImagePipe(videoPipeName)
                                .SetPixFormat(Formats.FFmpegPixFormat.rgb24)
                                .SetOutputVideoFrame(1)
                                .SetVideoFormat(FFmpegVideoFormat.image2)
                                .SetFramerate(this.FPS)
         ;
         if (size != null)
         {
             outputOptionArgs
             .SetVideoSize(size.Value);
         }
         this.ffmpegProcess = FFmpegService.StartFFmpegStandardOutput(fFmpegArgsBuilder.Args);
         return(this.ffmpegProcess.StandardOutput.BaseStream);
     }
     catch
     {
     }
     return(null);
 }
Exemple #2
0
        public IEnumerable <VideoFrameArgs> ReadVideoFrames(TimeSpan?seek = null, TimeSpan?seekEnd = null, Size?size = null, bool readByNativeFrame = true, CancellationToken?cancellationToken = null)
        {
            this.Dispose();
            TimeSpan          startSeek         = seek ?? TimeSpan.FromSeconds(0);
            FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();

            fFmpegArgsBuilder.GlobalOptionArgs
            .SetThreadQueueSize(512)
            .SetNoStandardInput()
            ;
            var inputOptionArgs = fFmpegArgsBuilder.SetInputFile(this.filePath)
                                  .SeekAccurate()
                                  .SetSeek(startSeek)
                                  .ReadByNativeFrame(() => readByNativeFrame)
            ;
            var outputOptionArgs = fFmpegArgsBuilder.SetOutputImagePipe(videoPipeName)
                                   .SetVideoFormat(FFmpegVideoFormat.image2pipe)
                                   .SetVideoCodec(FFmpegVideoCodec.rawvideo)
                                   .SetPixFormat(Formats.FFmpegPixFormat.rgb24)
                                   .SetFramerate(this.FPS)
                                   .SetSeekEnd(seekEnd ?? TimeSpan.MinValue, () => seekEnd != null)
                                   .SetVideoSize(this.GetSize(size))
            ;

            this.ffmpegProcess = FFmpegService.StartFFmpegStandardOutput(fFmpegArgsBuilder.Args);
            cancellationToken?.Register(() =>
            {
                this.Dispose();
            });
            int  frameIndex = (int)(startSeek.TotalMilliseconds / (1000.0 / this.FPS));
            Size bitmapSize = this.GetSize(size);

            byte[] frameDataBuffer = new byte[bitmapSize.Width * bitmapSize.Height * 3];
            byte[] buffer          = new byte[32768]; //ffmpeg的缓冲区大小被限定在32k 32768 似乎没有办法修改?
            int    read;
            int    readed = 0;

            while ((read = this.ffmpegProcess.StandardOutput.BaseStream.Read(buffer, 0, Math.Min(buffer.Length, frameDataBuffer.Length - readed))) > 0)
            {
                if (cancellationToken?.IsCancellationRequested ?? false)
                {
                    this.Dispose();
                    yield break;
                }
                Array.Copy(buffer, 0, frameDataBuffer, readed, read);
                readed += read;
                if (readed == frameDataBuffer.Length)
                {
                    //对每一个像素的颜色进行转化
                    for (int i = 0; i < frameDataBuffer.Length; i += 3)
                    {
                        byte temp = frameDataBuffer[i + 2];
                        frameDataBuffer[i + 2] = frameDataBuffer[i];
                        frameDataBuffer[i]     = temp;
                    }
                    yield return(new VideoFrameArgs(frameIndex++, frameDataBuffer));

                    readed = 0;
                }
            }
        }