C# ffmpeg.autogen cannot play local videos at normal speed or double speed? Only one line of code is needed

  1. First, make sure you have ffmpeg installed and reference the ffmpeg.autogen library in your project.

  2. Create an FFmpeg.AutoGen.FFmpegobject that will be your entry point for interacting with the ffmpeg library.

    FFmpeg.AutoGen.FFmpeg ffmpeg = new FFmpeg.AutoGen.FFmpeg();

  3. Initialize the ffmpeg library and open the video file.
    ffmpeg.av_register_all();
    ffmpeg.avcodec_register_all();
    
    string videoPath = "your_video_path";
    AVFormatContext* formatContext = null;
    
    // 打开视频文件
    if (ffmpeg.avformat_open_input(&formatContext, videoPath, null, null) != 0)
    {
        // 处理打开失败的情况
        return;
    }
    
    // 检索视频流信息
    if (ffmpeg.avformat_find_stream_info(formatContext, null) < 0)
    {
        // 处理获取流信息失败的情况
        return;
    }

  4. Find the video stream and get the video codec.
    AVCodec* videoCodec = null;
    int videoStreamIndex = ffmpeg.av_find_best_stream(formatContext, AVMediaType.AVMEDIA_TYPE_VIDEO, -1, -1, &videoCodec, 0);
    if (videoStreamIndex < 0)
    {
        // 处理未找到视频流的情况
        return;
    }
    
    // 获取视频解码器上下文
    AVCodecContext* codecContext = formatContext->streams[videoStreamIndex]->codec;

  5. Open the video codec.
    if (ffmpeg.avcodec_open2(codecContext, videoCodec, null) < 0)
    {
        // 处理视频解码器打开失败的情况
        return;
    }

  6. Create a video frame object and allocate memory.
    AVFrame* frame = ffmpeg.av_frame_alloc();
    AVFrame* frameRGB = ffmpeg.av_frame_alloc();
    
    int numBytes = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_RGB24, codecContext->width, codecContext->height, 1);
    byte* buffer = (byte*)ffmpeg.av_malloc((ulong)numBytes);
    
    ffmpeg.av_image_fill_arrays(frameRGB->data, frameRGB->linesize, buffer, AVPixelFormat.AV_PIX_FMT_RGB24, codecContext->width, codecContext->height, 1);

  7. Read video frames and decode them.
    AVPacket packet;
    
    while (ffmpeg.av_read_frame(formatContext, &packet) >= 0)
    {
        // 只处理视频流的数据包
        if (packet.stream_index == videoStreamIndex)
        {
            // 解码视频帧
            if (ffmpeg.avcodec_send_packet(codecContext, &packet) == 0)
            {
                while (ffmpeg.avcodec_receive_frame(codecContext, frame) == 0)
                {
                    // 在这里处理解码后的视频帧数据
                    
                    // 控制播放速度,例如使用 Thread.Sleep() 方法休眠一段时间
                    Thread.Sleep(33); // 按照每秒30帧的速度播放,休眠33毫秒
                    
                    // 释放帧数据的引用计数
                    ffmpeg.av_frame_unref(frame);
                }
            }
        }
    
        // 释放数据包的引用计数
        ffmpeg.av_packet_unref(&packet);
    }

When reading the stream in a loop, add sleep code. If the video is 25 frames per second, sleep for 40 milliseconds. If the video is 30 frames per second, sleep for 33 milliseconds, so that it can be played at normal speed.

If you want to realize local video playback at double speed, just control the sleep duration. Taking 25 frames per second as an example, at normal 1x speed, sleep for 40 milliseconds. If you want to achieve 2x speed, sleep for 20 milliseconds, at 4x speed, sleep for 10 milliseconds, and so on. The same goes for 30 frames per second.

Guess you like

Origin blog.csdn.net/u013543846/article/details/132295210