Newest 'ffmpeg' Questions - Stack Overflow

http://stackoverflow.com/questions/tagged/ffmpeg

Les articles publiés sur le site

  • orangepi zero 2w, ubuntu, using a usb webcam ffmpeg to record videos, low FPS [closed]

    28 janvier, par Qingfu Shi

    I use a OrpangePi zero 2w, USB HIK 2K Cam, to record videos. Ubuntu, ffmpeg installed, the cmd

    ffmpeg -f v4l2 -video_size 1920x1080 -r 25 -input_format mjpeg -i /dev/video1 -vf "transpose=1" -c:v libx264 -preset fast -crf 23 output.mp4
    

    I want the fps to be at least 25, so it looks smooth, but I only got about 4.7 fps.

    ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
      built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
      configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/aarch64-linux-gnu --incdir=/usr/include/aarch64-linux-gnu --arch=arm64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
      libavutil      56. 70.100 / 56. 70.100
      libavcodec     58.134.100 / 58.134.100
      libavformat    58. 76.100 / 58. 76.100
      libavdevice    58. 13.100 / 58. 13.100
      libavfilter     7.110.100 /  7.110.100
      libswscale      5.  9.100 /  5.  9.100
      libswresample   3.  9.100 /  3.  9.100
      libpostproc    55.  9.100 / 55.  9.100
    Input #0, video4linux2,v4l2, from '/dev/video1':
      Duration: N/A, start: 428045.804407, bitrate: N/A
      Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 1920x1080, 25 fps, 25 tbr, 1000k tbn, 1000k tbc
    File 'output.mp4' already exists. Overwrite? [y/N] y
    Stream mapping:
      Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
    Press [q] to stop, [?] for help
    [libx264 @ 0xaaab1677ccd0] using cpu capabilities: ARMv8 NEON
    [libx264 @ 0xaaab1677ccd0] profile High, level 4.0, 4:2:0, 8-bit
    [libx264 @ 0xaaab1677ccd0] 264 - core 163 r3060 5db6aa6 - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref=2 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=6 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=30 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'output.mp4':
      Metadata:
        encoder         : Lavf58.76.100
      Stream #0:0: Video: h264 (avc1 / 0x31637661), yuvj420p(pc, bt470bg/unknown/unknown, progressive), 1080x1920, q=2-31, 25 fps, 12800 tbn
        Metadata:
          encoder         : Lavc58.134.100 libx264
        Side data:
          cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
    frame=  264 fps=4.7 q=-1.0 Lsize=    6301kB time=00:00:10.44 bitrate=4944.2kbits/s speed=0.185x      
    video:6297kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.063708%
    [libx264 @ 0xaaab1677ccd0] frame I:2     Avg QP:22.43  size:140174
    [libx264 @ 0xaaab1677ccd0] frame P:69    Avg QP:22.70  size: 54079
    [libx264 @ 0xaaab1677ccd0] frame B:193   Avg QP:24.00  size: 12620
    [libx264 @ 0xaaab1677ccd0] consecutive B-frames:  1.5%  2.3%  2.3% 93.9%
    [libx264 @ 0xaaab1677ccd0] mb I  I16..4:  6.6% 85.8%  7.6%
    [libx264 @ 0xaaab1677ccd0] mb P  I16..4:  3.6% 12.5%  0.4%  P16..4: 26.9% 10.6%  7.1%  0.0%  0.0%    skip:39.0%
    [libx264 @ 0xaaab1677ccd0] mb B  I16..4:  0.8%  8.0%  0.1%  B16..8: 10.8%  3.0%  0.2%  direct:11.1%  skip:66.0%  L0:41.1% L1:42.2% BI:16.7%
    [libx264 @ 0xaaab1677ccd0] 8x8 transform intra:84.4% inter:78.9%
    [libx264 @ 0xaaab1677ccd0] coded y,uvDC,uvAC intra: 47.4% 51.8% 7.8% inter: 11.8% 11.9% 0.1%
    [libx264 @ 0xaaab1677ccd0] i16 v,h,dc,p: 43% 17% 13% 28%
    [libx264 @ 0xaaab1677ccd0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16% 15% 51%  3%  3%  3%  3%  3%  4%
    [libx264 @ 0xaaab1677ccd0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 19% 22% 18%  6%  7%  8%  6%  6%  7%
    [libx264 @ 0xaaab1677ccd0] i8c dc,h,v,p: 63% 19% 16%  2%
    [libx264 @ 0xaaab1677ccd0] Weighted P-Frames: Y:11.6% UV:8.7%
    [libx264 @ 0xaaab1677ccd0] ref P L0: 50.0% 50.0%
    [libx264 @ 0xaaab1677ccd0] ref B L0: 74.0% 26.0%
    [libx264 @ 0xaaab1677ccd0] ref B L1: 93.8%  6.2%
    [libx264 @ 0xaaab1677ccd0] kb/s:4884.46
    

    If change resolution to 1280720, fps increase to 12-13, change to 640360, fps increase to 27-28

    the webcam supports the following fmts

    v4l2-ctl --device=/dev/video1 --list-formats-ext
    
    ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture
    
        [0]: 'YUYV' (YUYV 4:2:2)
            Size: Discrete 640x360
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 640x480
                Interval: Discrete 0.040s (25.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
        [1]: 'MJPG' (Motion-JPEG, compressed)
            Size: Discrete 640x360
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 1280x720
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 1280x960
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 1920x1080
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 2048x1536
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 2560x1440
                Interval: Discrete 0.040s (25.000 fps)
            Size: Discrete 640x480
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
    

    but I want the video at least 1080p@30fps. What's the bottleneck? is it possible to modify the cmd to achieve this? OrangePi zero 2w, use an AllWinner H618 cpu, with 1G RAM, 64G v10 sd-card.

  • Writing a video frame by frame using ffmpeg

    28 janvier, par Chris

    I am trying to write a video frame by frame using ffmpeg as explained here: http://zulko.github.io/blog/2013/09/27/read-and-write-video-frames-in-python-using-ffmpeg/

    However, I am always getting an OSError: [Errno 22] Invalid argument. I am on Windows 7 and using Python 3.4. Here is the code:

    import subprocess as sp
    import numpy as np
    import time
    
    ffmpeg_bin = r'C:\path\to\ffmpeg\ffmpeg.exe'
    
    command = [ffmpeg_bin,
               '-y', # (optional) overwrite output file if it exists
               '-f', 'rawvideo',
               '-vcodec','rawvideo',
               '-s', '420x360', # size of one frame
               '-pix_fmt', 'rgb24',
               '-r', '24', # frames per second
               '-i', '-', # The imput comes from a pipe
               '-an', # Tells FFMPEG not to expect any audio
               '-vcodec', 'mpeg',
               'my_output_videofile.mp4' ]
    
    proc = sp.Popen(command, stdin=sp.PIPE, stderr=sp.PIPE)
    
    a = np.zeros((360, 420, 3), dtype=np.uint8)
    
    for ii in range(5*24):
        print(ii)
        proc.stdin.write(a.tostring())
        time.sleep(1/24)
    
    proc.stdin.close()
    proc.stderr.close()
    proc.wait()
    

    Any help is greatly appreciated.

    EDIT: As requested here the detailed output of the program

    0
    1
    Traceback (most recent call last):
      File ".\write_dummy_video.py", line 25, in 
        proc.stdin.write(a.tostring())
    OSError: [Errno 22] Invalid argument
    

    Interestingly, if I comment line number 26 (i.e. time.sleep(1/24)) the error message changes slightly but the loop still only runs twice. Here is the error output:

    0
    1
    Traceback (most recent call last):
      File ".\write_dummy_video.py", line 25, in 
        proc.stdin.write(a.tostring())
    BrokenPipeError: [Errno 32] Broken pipe
    
  • How to set PTS value to .mp4 video frames without losing video quality

    27 janvier, par Goan

    I have searched for a solution to this problem for a while now, and tried many different approaches without any success.

    I have an .mp4 video (no audio) in 30Hz along with a text file timestamps.txt containing exact timestamps for each frame of the video. My goal is to embed the timestamps into the frames metadata without losing video quality.

    E.g. the current video timestamps (which is exactly 30Hz):

    0.0333
    0.0666
    0.0999
    ...
    

    I aim to embed exact timestamps such as (which could yield e.g. 29.94Hz):

    0.0313
    0.0656
    0.0975
    ...
    

    I first tried the ffmpeg -filter_complex and -vf without any success. Then I tried using PyAv (pyav==13.1.0) to set the timestamp frame by frame with two different approaches:

    Approach 1: Using .add_stream(template=...)

    ...
    TIMEBASE = Fraction(1, 10000)
    pts_stamps = load_timestamps() # First five pts_stamps are [0,316,635,970,1290...]
    
    # Open the input container and stream
    input_container = av.open()
    input_stream = input_container.streams.video[0]
    
    # Create an output container and configure the output stream using template
    output_container = av.open(, mode="w")
    output_stream = output_container.add_stream(template=input_stream)
    
    # Iterate through the frames and set the PTS
    for i, frame in tqdm(enumerate(input_container.decode(video=0))):
        frame.pts = pts_stamps[i]
        frame.time_base = TIMEBASE
    
        for packet in output_stream.encode(frame):
            output_container.mux(packet)
    
    # Finalize encoding and close the containers
    for packet in output_stream.encode():
        output_container.mux(packet)
    
    output_container.close()
    input_container.close()
    

    However, this resulted in the error "ValueError: Cannot rebase to zero time." which seems to be a relatively common issue which I don't seem to be able to resolve. Not sure why.

    Approach 2: Setting the output container settings manually

    ...
    TIMEBASE = Fraction(1, 10000)
    pts_stamps = load_timestamps() # First five pts_stamps are [0,316,635,970,1290...]
    
    # Open the input container and stream
    input_container = av.open()
    input_stream = input_container.streams.video[0]
    
    # Create an output container and configure the output stream using template
    output_container = av.open(, mode="w")
    output_stream = output_container.add_stream(input_stream.codec.name, rate=input_stream.average_rate)
    output_stream.width = input_stream.width
    output_stream.height = input_stream.height
    output_stream.pix_fmt = input_stream.pix_fmt
    output_stream.bit_rate = input_stream.bit_rate
    output_stream.time_base = input_stream.time_base
    output_stream.options = {"crf": "0"}
    
    # Iterate through the frames and set the PTS
    for i, frame in tqdm(enumerate(input_container.decode(video=0))):
        frame.pts = pts_stamps[i]
        frame.time_base = TIMEBASE
    
        for packet in output_stream.encode(frame):
            output_container.mux(packet)
    
    # Finalize encoding and close the containers
    for packet in output_stream.encode():
        output_container.mux(packet)
    
    output_container.close()
    input_container.close()
    

    This result in a video with correct timestamps. However, the quality is not the same. The output file is 4x smaller, and there seem to be an average pixel value different of ~2.7 pixels for each frame. I.e. it seems the encoding is lossy.

    Any tips on how to resolve this?

  • Extract just the audio link from a youtube video without converting

    27 janvier, par MR-4O4

    I know there are hundreds of sites to convert youtube video to mp3. Most of them do it by first downloading the video and then converting it to mp3(or any other audio format) on their server using youtube-dl, ffmpeg or similar programs.

    What I want to know is, is there any way I can just extract the audio link for any youtube video? I don't know if it's possible but I saw a couple of websites doing it .

    First Website : Openaisearch.com This website simply gives a download link for the audio(getting it from youtube videos). I searched for a song and saw the download url, it looked something like this :

    https://redirector.googlevideo.com/videoplayback?source=youtube&requiressl=yes&clen=3814013&upn=dzwY9aUVYME&lmt=1469875393441562&expire=1484854959&mime=audio%2Fmp4&nh=IgpwcjAxLnNlYTA5Kg01Mi45NS4yMTYuMTAy&itag=140........... 
    

    I believe that this is not done by first downloading and converting the video to audio format(Correct me if I am wrong). Although the file which gets downloaded after using this link is without any extension, but adding ".m4a" at the end of downloaded file does the work.

    Second Website : http://keepvid.com/?url=https://www.youtube.com/watch?v=PT2_F-1esPk

    Again similar website with similar audio link. You can check by visiting the URL and see link of audio files.

    Any idea how these websites get that "googlevideo.com" link? Do they scrap the youtube video links or something?

    Thanks.

  • No Audio in Recorded File from IP Camera using ffmpeg

    26 janvier, par LeXela-ED

    I'm trying to record video and audio from an IP camera equipped with a microphone. Below is a simplified version of my code, which compiles and runs without errors:

    #include avformat.h>
    #include avcodec.h>
    #include opt.h>
    #include 
    #include 
    
    #define AUDIO_CODEC "aac"
    
    void log_error(const char *message, int error_code) {
        char error_buffer[AV_ERROR_MAX_STRING_SIZE];
        av_strerror(error_code, error_buffer, sizeof(error_buffer));
        fprintf(stderr, "%s: %s\n", message, error_buffer);
        exit(1);
    }
    
    int main(int argc, char *argv[]) {
         const char *input_url = "rtsp://admin:123456@192.168.1.99:554/mode=real&idc=1&ids=1";
        const char *output_file = "D:/abc.ts"; // MPEG-TS file
    
        avformat_network_init();
    
        AVFormatContext *input_ctx = NULL;
        AVFormatContext *output_ctx = NULL;
        AVStream *video_stream = NULL, *audio_stream = NULL;
        AVCodecContext *audio_codec_ctx = NULL;
        AVCodec *audio_codec = NULL;
        int ret;
    
        // Open input stream
        if ((ret = avformat_open_input(&input_ctx, input_url, NULL, NULL)) < 0) {
            log_error("Failed to open input", ret);
        }
    
        if ((ret = avformat_find_stream_info(input_ctx, NULL)) < 0) {
            log_error("Failed to find stream info", ret);
        }
    
        // Find video and audio streams
        int video_stream_index = -1, audio_stream_index = -1;
        for (int i = 0; i < input_ctx->nb_streams; i++) {
            if (input_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                video_stream_index = i;
            } else if (input_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
                audio_stream_index = i;
            }
        }
    
        if (video_stream_index == -1) {
            fprintf(stderr, "No video stream found\n");
            exit(1);
        }
        if (audio_stream_index == -1) {
            fprintf(stderr, "No audio stream found\n");
            exit(1);
        }
    
        // Allocate output context
        avformat_alloc_output_context2(&output_ctx, NULL, NULL, output_file);
        if (!output_ctx) {
            fprintf(stderr, "Failed to create output context\n");
            exit(1);
        }
    
        // Copy video stream
        video_stream = avformat_new_stream(output_ctx, NULL);
        if (!video_stream) {
            fprintf(stderr, "Failed to create video stream\n");
            exit(1);
        }
        avcodec_parameters_copy(video_stream->codecpar, input_ctx->streams[video_stream_index]->codecpar);
        video_stream->codecpar->codec_tag = 0;
    
        // Transmux audio stream to AAC
        audio_codec = avcodec_find_encoder_by_name(AUDIO_CODEC);
        if (!audio_codec) {
            fprintf(stderr, "AAC codec not found\n");
            exit(1);
        }
    
        audio_stream = avformat_new_stream(output_ctx, audio_codec);
        if (!audio_stream) {
            fprintf(stderr, "Failed to create audio stream\n");
            exit(1);
        }
    
        audio_codec_ctx = avcodec_alloc_context3(audio_codec);
        if (!audio_codec_ctx) {
            fprintf(stderr, "Failed to allocate audio codec context\n");
            exit(1);
        }
    
        // Set audio codec parameters
        audio_codec_ctx->sample_fmt = audio_codec->sample_fmts ? audio_codec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
        audio_codec_ctx->bit_rate = 64000;
        audio_codec_ctx->sample_rate = 44100;
    
        // Use AVChannelLayout for channel configuration
        AVChannelLayout stereo_layout = AV_CHANNEL_LAYOUT_STEREO;
        av_channel_layout_copy(&audio_codec_ctx->ch_layout, &stereo_layout);
    
        if (output_ctx->oformat->flags & AVFMT_GLOBALHEADER) {
            audio_codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
        }
    
        if ((ret = avcodec_open2(audio_codec_ctx, audio_codec, NULL)) < 0) {
            log_error("Failed to open audio codec", ret);
        }
    
        avcodec_parameters_from_context(audio_stream->codecpar, audio_codec_ctx);
    
        // Open output file
        if (!(output_ctx->oformat->flags & AVFMT_NOFILE)) {
            if ((ret = avio_open(&output_ctx->pb, output_file, AVIO_FLAG_WRITE)) < 0) {
                log_error("Failed to open output file", ret);
            }
        }
    
        // Write header
        if ((ret = avformat_write_header(output_ctx, NULL)) < 0) {
            log_error("Failed to write header", ret);
        }
    
        // Read and write packets
        AVPacket pkt;
        int count = 0;
        while (count++, count < 500) {
            if ((ret = av_read_frame(input_ctx, &pkt)) < 0) {
                break; // End of stream or error
            }
    
            if (pkt.stream_index == video_stream_index) {
                // Video packet: copy as-is
                pkt.stream_index = video_stream->index;
            } else if (pkt.stream_index == audio_stream_index) {
                // Audio packet: transmux to AAC
                pkt.stream_index = audio_stream->index;
            } else {
                av_packet_unref(&pkt);
                continue;
            }
    
            av_packet_rescale_ts(&pkt, input_ctx->streams[pkt.stream_index]->time_base, output_ctx->streams[pkt.stream_index]->time_base);
    
            if ((ret = av_interleaved_write_frame(output_ctx, &pkt)) < 0) {
                log_error("Failed to write frame", ret);
            }
    
            av_packet_unref(&pkt);
        }
    
        // Write trailer
        av_write_trailer(output_ctx);
    
        // Cleanup
        avcodec_free_context(&audio_codec_ctx);
        avformat_close_input(&input_ctx);
        if (output_ctx && !(output_ctx->oformat->flags & AVFMT_NOFILE)) {
            avio_closep(&output_ctx->pb);
        }
        avformat_free_context(output_ctx);
    
        printf("Recording completed successfully.\n");
        return 0;
    }
    

    Everything seems to work fine during recording, but when I play back the recorded file, there’s no audio. Here’s the output from ffprobe:

    Input #0, mpegts, from 'D:/abc.ts':
      Duration: 00:00:11.92, start: 0.000000, bitrate: 1897 kb/s
      Program 1
        Metadata:
          service_name    : Service01
          service_provider: FFmpeg
      Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuvj420p(pc, bt709, progressive), 1920x1080, 25 fps, 25 tbr, 90k tbn
      Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), stereo, fltp, 167 kb/s
    

    What might I be missing here? I'd greatly appreciate any guidance or suggestions. Thanks in advance for your help!