Newest 'ffmpeg' Questions - Stack Overflow

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

Les articles publiés sur le site

  • ffmpeg remove Non-Monotonous DTS frames

    24 mars, par MiGu3X

    Is it possible to stream copy a .ts file to another .ts file by removing the Non-Monotonous DTS frames? These frames usually also have a smaller resolution than the video I am trying to copy. I attempted this with VideoReDo but it did not work and I cannot seem to make it work.

    Also, the MediaInfo for the video after remixed to Matrosks shows this:

    Video
    ID                                       : 1
    Format                                   : AVC
    Format/Info                              : Advanced Video Codec
    Format profile                           : High@L3.2
    Format settings                          : CABAC / 2 Ref Frames
    Format settings, CABAC                   : Yes
    Format settings, RefFrames               : 2 frames
    Codec ID                                 : V_MPEG4/ISO/AVC
    Duration                                 : 2 h 35 min
    Nominal bit rate                         : 6 000 kb/s
    Width                                    : 896 pixels
    Original width                           : 1 280 pixels
    Height                                   : 504 pixels
    Original height                          : 720 pixels
    Display aspect ratio                     : 16:9
    Frame rate mode                          : Constant
    Frame rate                               : 30.000 FPS
    Original frame rate                      : 60.000 FPS
    Color space                              : YUV
    Chroma subsampling                       : 4:2:0
    Bit depth                                : 8 bits
    Scan type                                : Progressive
    Bits/(Pixel*Frame)                       : 0.443
    Writing library                          : x264 core 148 r2579M 73ae2d1
    Encoding settings                        : cabac=1 / ref=2 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=2 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=0 / threads=4 / lookahead_threads=1 / sliced_threads=0 / nr=250 / decimate=1 / interlaced=0 / bluray_compat=0 / stitchable=1 / constrained_intra=0 / bframes=0 / weightp=1 / keyint=122 / keyint_min=12 / scenecut=40 / intra_refresh=0 / rc_lookahead=10 / rc=2pass / mbtree=1 / bitrate=6000 / ratetol=1.0 / qcomp=0.60 / qpmin=5 / qpmax=69 / qpstep=4 / cplxblur=20.0 / qblur=0.5 / ip_ratio=1.40 / aq=1:1.00
    Default                                  : Yes
    Forced                                   : No
    

    Thanks for the help!

  • How to set pts, dts and duration in ffmpeg library ?

    24 mars, par hslee

    I want to pack some compressed video packets(h.264) to ".mp4" container. One word, Muxing, no decoding and no encoding. And I have no idea how to set pts, dts and duration.

    1. I get the packets with "pcap" library.
    2. I removed headers before compressed video data show up. e.g. Ethernet, VLAN.
    3. I collected data until one frame and decoded it for getting information of data. e.g. width, height. (I am not sure that it is necessary)
    4. I initialized output context, stream and codec context.
    5. I started to receive packets with "pcap" library again. (now for muxing)
    6. I made one frame and put that data in AVPacket structure.
    7. I try to set PTS, DTS and duration. (I think here is wrong part, not sure though)

    *7-1. At the first frame, I saved time(msec) with packet header structure.

    *7-2. whenever I made one frame, I set parameters like this : PTS(current time - start time), DTS(same PTS value), duration(current PTS - before PTS)

    I think it has some error because :

    1. I don't know how far is suitable long for dts from pts.

    2. At least, I think duration means how long time show this frame from now to next frame, so It should have value(next PTS - current PTS), but I can not know the value next PTS at that time.

    It has I-frame only.

    // make input context for decoding
    
    AVFormatContext *&ic = gInputContext;
    
    ic = avformat_alloc_context();
    
    AVCodec *cd = avcodec_find_decoder(AV_CODEC_ID_H264);
    
    AVStream *st = avformat_new_stream(ic, cd);
    
    AVCodecContext *cc = st->codec;
    
    avcodec_open2(cc, cd, NULL);
    
    // make packet and decode it after collect packets is be one frame
    
    gPacket.stream_index = 0;
    
    gPacket.size    = gPacketLength[0];
    
    gPacket.data    = gPacketData[0];
    
    gPacket.pts     = AV_NOPTS_VALUE;
    
    gPacket.dts     = AV_NOPTS_VALUE;
    
    gPacket.flags   = AV_PKT_FLAG_KEY;
    
    avcodec_decode_video2(cc, gFrame, &got_picture, &gPacket);
    
    // I checked automatically it initialized after "avcodec_decode_video2"
    
    // put some info that I know that not initialized
    
    cc->time_base.den   = 90000;
    
    cc->time_base.num   = 1;
    
    cc->bit_rate    = 2500000;
    
    cc->gop_size    = 1;
    
    // make output context with input context
    
    AVFormatContext *&oc = gOutputContext;
    
    avformat_alloc_output_context2(&oc, NULL, NULL, filename);
    
    AVFormatContext *&ic = gInputContext;
    
    AVStream *ist = ic->streams[0];
    
    AVCodecContext *&icc = ist->codec;
    
    AVStream *ost = avformat_new_stream(oc, icc->codec);
    
    AVCodecContext *occ = ost->codec;
    
    avcodec_copy_context(occ, icc);
    
    occ->flags |= CODEC_FLAG_GLOBAL_HEADER;
    
    avio_open(&(oc->pb), filename, AVIO_FLAG_WRITE);
    
    // repeated part for muxing
    
    AVRational Millisecond = { 1, 1000 };
    
    gPacket.stream_index = 0;
    
    gPacket.data = gPacketData[0];
    
    gPacket.size = gPacketLength[0];
    
    gPacket.pts = av_rescale_rnd(pkthdr->ts.tv_sec * 1000 /
    
        + pkthdr->ts.tv_usec / 1000 /
    
        - gStartTime, Millisecond.den, ost->time_base.den, /
    
        (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
    
    gPacket.dts = gPacket.pts;
    
    gPacket.duration = gPacket.pts - gPrev;
    
    gPacket.flags = AV_PKT_FLAG_KEY;
    
    gPrev = gPacket.pts;
    
    av_interleaved_write_frame(gOutputContext, &gPacket);
    

    Expected and actual results is a .mp4 video file that can play.

  • Non-monotonous DTS after 26:30:02.81 recording time

    24 mars, par micha

    I record an hls stream and after 26:30:02.81 there come the message:

    [http @ 0x558330f5ba80] Opening 'http://de-origin-live-be-01.3qsdn.com:8081/3279/996191_PwxkbnqRThCDGXVr/l_94_95438333_16449.ts?nimblesessionid=2106' for reading
    frame=2289669 fps= 24 q=-1.0 size=25056768kB time=26:30:02.81 bitrate=2151.6kbits/s speed=   1x    
    [mpegts @ 0x558330f07280] Invalid timestamps stream=0, pts=10378, dts=8589926250, size=11200
    [mpegts @ 0x558330f07280] Invalid timestamps stream=0, pts=2908, dts=8589929940, size=3407
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744840, current: -3185972; changing to 8586744841. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598864, current: -1698561; changing to 4579598865. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598865, current: -1697537; changing to 4579598866. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598866, current: -1696513; changing to 4579598867. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744841, current: -3182282; changing to 8586744842. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598867, current: -1695489; changing to 4579598868. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598868, current: -1694465; changing to 4579598869. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:1; previous: 4579598869, current: -1693441; changing to 4579598870. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744842, current: -3178502; changing to 8586744843. This may result in incorrect timestamps in the output file.
    [mp4 @ 0x558330f20bc0] Non-monotonous DTS in output stream 0:0; previous: 8586744843, current: -3174722; changing to 8586744844. This may result in incorrect timestamps in the output file.
    

    There is no more video written to the file at this time but ffmpeg is not stopping. If i stop it manual after 30 hours the file is only 26 hours 30 minutes long.

    How to reproduce:

    ffmpeg -progress recorder.progress -reconnect 1 -user_agent 'sdn/1.0' -i http://source/playlist.m3u8 -codec copy -bsf:a aac_adtstoasc record.mp4
    
    ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
      built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
      configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-demuxer=dash --enable-decoder=hevc --enable-libxml2 --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib --extra-libs=-ldl --prefix=/opt/ffmpeg
      libavutil      56. 31.100 / 56. 31.100
      libavcodec     58. 54.100 / 58. 54.100
      libavformat    58. 29.100 / 58. 29.100
      libavdevice    58.  8.100 / 58.  8.100
      libavfilter     7. 57.100 /  7. 57.100
      libavresample   4.  0.  0 /  4.  0.  0
      libswscale      5.  5.100 /  5.  5.100
      libswresample   3.  5.100 /  3.  5.100
      libpostproc    55.  5.100 / 55.  5.100
    
  • Bash script to recursive find and convert movies

    24 mars, par Jacco

    in my large movie collection I would like to search for movies with the primary (first) audio track with DTS coding to be converted to Dolby.

    My problem would be the first track I think. My current bash script will list any movie containing a DTS track, but does not specify which track.

    #!/bin/bash
    # My message to create DTS list
    find /home/Movies -name '*.mkv' | while read f
    do
    if mediainfo "$f" | grep A_DTS; then
    echo $f 
    fi
    done
    

    After that I would like to run this command

    ffmpeg -i $f -map 0:v -map 0:a:0 -map 0:a -map 0:s -c:v copy -c:a copy -c:s copy -c:a:0 ac3 -b:a:0 640k $f
    

    or is there a way to move all the audio tracks down and adding the new AAC track?

    ###Progress

    Thanks to @llogan I have finetuned the bash to find the required files.

    #!/bin/bash
    # My DTS conversion script
    # credits to llogan
    
    find /Mymovies -name '*.mkv' | while read f
    do
     if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$f" | grep dts; then
     echo "$f"
    fi
    done
    

    Now digging into the command I think I may have a working command. Anybody spot a problem?

    ffmpeg -i $f
          -map 0:v -c:v copy
          -map 0:a:0? -c:a:0 ac3
          -map 0:a:0? -c:a:1 copy
          -map 0:a:1? -c:a:2 copy
          -map 0:a:2? -c:a:3 copy
          -map 0:a:3? -c:a:4 copy
          -map 0:a:4? -c:a:5 copy
          -map 0:a:5? -c:a:6 copy
          -map 0:a:6? -c:a:7 copy
          -map 0:a:7? -c:a:8 copy
          -map 0:a:8? -c:a:9 copy
          -map 0:s? -c copy
          -b:a:0 640k
    /tmp/output.mkv
    mv $f /home/DTS_BACKUP/
    mv /tmp/output.mkv $f
    rm /tmp/output.mkv
    

    So the end result would look like:

    #!/bin/bash
    # My DTS conversion script
    # credits to llogan
    find /Mymovies -name '*.mkv' | while read f
    do
     if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$f" | grep dts; then
    
    ffmpeg -i $f
              -map 0:v -c:v copy
              -map 0:a:0? -c:a:0 ac3
              -map 0:a:0? -c:a:1 copy
              -map 0:a:1? -c:a:2 copy
              -map 0:a:2? -c:a:3 copy
              -map 0:a:3? -c:a:4 copy
              -map 0:a:4? -c:a:5 copy
              -map 0:a:5? -c:a:6 copy
              -map 0:a:6? -c:a:7 copy
              -map 0:a:7? -c:a:8 copy
              -map 0:a:8? -c:a:9 copy
              -map 0:s? -c copy
              -b:a:0 640k
    /tmp/output.mkv
    mv $f /home/DTS_BACKUP/
    mv /tmp/output.mkv $f
    rm /tmp/output.mkv
    
    fi
    done
    
  • Convert DTS to AC3 but only if there is no AC3 track already present in container

    24 mars, par Domagoj

    I have sound system that does not support DTS only AC3. I'm automating the process using bash that detects when movie was added to folder, downloads subtitles and converts audio track to AC3 using this command (one part of it):

    ffmpeg -i "{{episode}}" -map 0:v -map 0:a:0 -map 0:a -map 0:s -c:v copy -c:a copy -c:s copy -c:a:0 ac3 -b:a:0 640k "{{directory}}"/{{episode_name}}temp2.mkv

    This works without issue and I end up with a .mkv file that contains original DTS audio track and newly created AC3 audio track. The issue is that some files already contain both AC3 and DTS tracks and in those cases I end up with two AC3 tracks and one DTS track. Another issue is that this command is triggered every time there is update to subtitles. So it's possible that the command will execute multiple times in a period of a few days and the container will have X number of the AC3 tracks.

    I need a way to detect if file already contains AC3 track before I initiate command from above, but I'm not sure what the command would be. Any help is appreciated!