Newest 'ffmpeg' Questions - Stack Overflow

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

Les articles publiés sur le site

  • cause of mpeg-dash delay

    14 février 2017, par evan

    I have created mpeg-dash stream from a MP4 file. I trascoded my videos to MP4 using ffmpeg library and made the mpeg-dash using MP4Box. my resault mpeg-dash video seems to have some buffering problem (buffer stall I guess) and also 5 second delay when I seek in the video. the startup delay seems to be fine. I was wondering what is the cause of this delay? is it coming from my ffmpeg and transcode commands? or is it coming from MP4box and the process of dashing? I need to find the source to be able to solve it. any ideas? I would realy appreciate any help.

    these are my ffmpeg codes:

    ffmpeg -i main720.MTS -movflags faststart -vcodec libx264 -r 24 -tune zerolatency -tune fastdecode -bf 0 -slices 0 -x264opts intra_refresh=1 -g 96 -b:v 700k -maxrate 700k -bufsize 400k -an -s 640*360 -ss 00:00:00 -t 00:02:00 main720_700_video.mp4

    ffmpeg -i main720.MTS -movflags faststart -acodec libmp3lame -b:a 128k -vn -ss 00:00:00 -t 00:02:00 main720_700_audio.mp4

    and this my MP4Box command:

    MP4Box -dash 4000 -frag 4000 -profile onDamand -rap -segment-name %s_ -out manifest.mpd main720_300_video.mp4 main720_700_video.mp4 main720_300_audio.mp4

  • Stream publishing using ffmpeg rtmp : network bandwidth not fully utilized

    14 février 2017, par DeducibleSteak

    I'm developing an application that needs to publish a media stream to an rtmp "ingestion" url (as used in YouTube Live, or as input to Wowza Streaming Engine, etc), and I'm using the ffmpeg library (programmatically, from C/C++, not the command line tool) to handle the rtmp layer. I've got a working version ready, but am seeing some problems when streaming higher bandwidth streams to servers with worse ping. The problem exists both when using the ffmpeg "native"/builtin rtmp implementation and the librtmp implementation.

    When streaming to a local target server with low ping through a good network (specifically, a local Wowza server), my code has so far handled every stream I've thrown at it and managed to upload everything in real time - which is important, since this is meant exclusively for live streams.

    However, when streaming to a remote server with a worse ping (e.g. the youtube ingestion urls on a.rtmp.youtube.com, which for me have 50+ms pings), lower bandwidth streams work fine, but with higher bandwidth streams the network is underutilized - for example, for a 400kB/s stream, I'm only seeing ~140kB/s network usage, with a lot of frames getting delayed/dropped, depending on the strategy I'm using to handle network pushback.

    Now, I know this is not a problem with the network connection to the target server, because I can successfully upload the stream in real time when using the ffmpeg command line tool to the same target server or using my code to stream to a local Wowza server which then forwards the stream to the youtube ingestion point.

    So the network connection is not the problem and the issue seems to lie with my code.

    I've timed various parts of my code and found that when the problem appears, calls to av_write_frame / av_interleaved_write_frame (I never mix & match them, I am always using one version consistently in any specific build, it's just that I've experimented with both to see if there is any difference) sometimes take a really long time - I've seen those calls sometimes take up to 500-1000ms, though the average "bad case" is in the 50-100ms range. Not all calls to them take this long, most return instantly, but the average time spent in these calls grows bigger than the average frame duration, so I'm not getting a real time upload anymore.

    The main suspect, it seems to me, could be the rtmp Acknowledgement Window mechanism, where a sender of data waits for a confirmation of receipt after sending every N bytes, before sending any more data - this would explain the available network bandwidth not being fully used, since the client would simply sit there and wait for a response (which takes a longer time because of the lower ping), instead of using the available bandwidth. Though I haven't looked at ffmpeg's rtmp/librtmp code to see if it actually implements this kind of throttling, so it could be something else entirely.

    The full code of the application is too much to post here, but here are some important snippets:

    Format context creation:

    const int nAVFormatContextCreateError = avformat_alloc_output_context2(&m_pAVFormatContext, nullptr, "flv", m_sOutputUrl.c_str());
    

    Stream creation:

    m_pVideoAVStream = avformat_new_stream(m_pAVFormatContext, nullptr);
    m_pVideoAVStream->id = m_pAVFormatContext->nb_streams - 1;
    
    m_pAudioAVStream = avformat_new_stream(m_pAVFormatContext, nullptr);
    m_pAudioAVStream->id = m_pAVFormatContext->nb_streams - 1;
    

    Video stream setup:

    m_pVideoAVStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    m_pVideoAVStream->codecpar->codec_id = AV_CODEC_ID_H264;
    m_pVideoAVStream->codecpar->width = nWidth;
    m_pVideoAVStream->codecpar->height = nHeight;
    m_pVideoAVStream->codecpar->format = AV_PIX_FMT_YUV420P;
    m_pVideoAVStream->codecpar->bit_rate = 10 * 1000 * 1000;
    m_pVideoAVStream->time_base = AVRational { 1, 1000 };
    
    m_pVideoAVStream->codecpar->extradata_size = int(nTotalSizeRequired);
    m_pVideoAVStream->codecpar->extradata = (uint8_t*)av_malloc(m_pVideoAVStream->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
    // Fill in the extradata here - I'm sure I'm doing that correctly.
    

    Audio stream setup:

    m_pAudioAVStream->time_base = AVRational { 1, 1000 };
    // Let's leave creation of m_pAudioCodecContext out of the scope of this question, I'm quite sure everything is done right there.
    const int nAudioCodecCopyParamsError = avcodec_parameters_from_context(m_pAudioAVStream->codecpar, m_pAudioCodecContext);
    

    Opening the connection:

    const int nAVioOpenError = avio_open2(&m_pAVFormatContext->pb, m_sOutputUrl.c_str(), AVIO_FLAG_WRITE);
    

    Starting the stream:

    AVDictionary * pOptions = nullptr;
    const int nWriteHeaderError = avformat_write_header(m_pAVFormatContext, &pOptions);
    

    Sending a video frame:

    AVPacket pkt = { 0 };
    av_init_packet(&pkt);
    pkt.dts = nTimestamp;
    pkt.pts = nTimestamp;
    pkt.duration = nDuration; // I know what I have the wrong duration sometimes, but I don't think that's the issue.
    pkt.data = pFrameData;
    pkt.size = pFrameDataSize;
    pkt.flags = bKeyframe ? AV_PKT_FLAG_KEY : 0;
    pkt.stream_index = m_pVideoAVStream->index;
    const int nWriteFrameError = av_write_frame(m_pAVFormatContext, &pkt); // This is where too much time is spent.
    

    Sending an audio frame:

    AVPacket pkt = { 0 };
    av_init_packet(&pkt);
    pkt.pts = m_nTimestampMs;
    pkt.dts = m_nTimestampMs;
    pkt.duration = m_nDurationMs;
    pkt.stream_index = m_pAudioAVStream->index;
    const int nWriteFrameError = av_write_frame(m_pAVFormatContext, &pkt);
    

    Any ideas? Am I on the right track with thinking about the Acknowledgement Window? Am I doing something else completely wrong?

  • How to fetch video frame and its timestamp from ffmpeg to python code

    14 février 2017, par vijiboy

    Searching for an alternative as OpenCV would not provide timestamps which were required in my computer vision algorithm, I found this excellent article https://zulko.github.io/blog/2013/09/27/read-and-write-video-frames-in-python-using-ffmpeg/
    Working up the code on windows I still could'nt get the frame timestamps. I recollected seeing on ffmpeg forum somewhere that the video filters like showinfo are bypassed when redirected.

    Here's what I tried:

    import subprocess as sp
    import numpy
    import cv2
    
    command = [ 'ffmpeg', 
                '-i', 'e:\sample.wmv',
                '-pix_fmt', 'rgb24',
                '-vcodec', 'rawvideo',
                '-vf', 'showinfo', # video filter - showinfo will provide frame timestamps
                '-an','-sn', #-an, -sn disables audio and sub-title processing respectively
                '-f', 'image2pipe', '-'] # we need to output to a pipe
    
    pipe = sp.Popen(command, stdout = sp.PIPE, stderr = sp.STDOUT) # TODO someone on ffmpeg forum said video filters (e.g. showinfo) are bypassed when stdout is redirected to pipes??? 
    
    for i in range(10):
        raw_image = pipe.stdout.read(1280*720*3)
        img_info = pipe.stdout.read(244) # 244 characters is the current output of showinfo video filter
        print "showinfo output", img_info
        image1 =  numpy.fromstring(raw_image, dtype='uint8')
        image2 = image1.reshape((720,1280,3))  
    
        # write video frame to file just to verify
        videoFrameName = 'Video_Frame{0}.png'.format(i)
        cv2.imwrite(videoFrameName,image2)
    
        # throw away the data in the pipe's buffer.
        pipe.stdout.flush()
    

    So how to still get the frame timestamps from ffmpeg into python code so that it can be used in my computer vision algorithm ...

  • Start rtl_fm and ffmpeg when connecting to a controller and return the stream

    14 février 2017, par yglodt

    I would like to run rtl_fm and ffmpeg on demand from within a Spring Controller, with parameters from the calling url, and return the stream to the caller.

    The command-line to run would more or less be:

    rtl_fm -f 105000K -M fm -s 170k -A std -l 0 -E deemp -r 44.1k | \
    ffmpeg -f s16le -ac 1 -i pipe:0 -acodec libmp3lame -ab 128k -f mpeg -
    

    105000 is the frequency in kHz and should be taken from a request parameter or path variable.

    The url (Controller) should return the stream so that it can be played in a remote vlc.

    When disconnecting from the url (stopping vlc playback), the rtl_fm and ffmpeg processes should be ended immediately.

    Is that feasible?

  • FFMPEG conversion images to video PHP [on hold]

    14 février 2017, par Alex de la Rosa

    Hello I would like to know what code in php I have to use to create a video from some JPG images.