Newest 'ffmpeg' Questions - Stack Overflow

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

Les articles publiés sur le site

  • FFmpeg : Remux f4v cutted from stream to mp4

    13 mai 2019, par Martin

    I have a mp4 file cutted from a H.264/AAC stream with Wowza Media Server. After the cutting, the file was forced to mp4 format with the following command:

    ffmpeg -i wowza_output_file -vcodec copy -acodec copy -f mp4 -y wowza_output_file_copy
    

    From there I renamed it to test_f4v.mp4 and took ffprobe, to take a look at the file:

    ffprobe version 0.8, Copyright (c) 2007-2011 the FFmpeg developers
      built on Jul 20 2011 13:32:19 with gcc 4.4.3
      configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264
      libavutil    51.  9. 1 / 51.  9. 1
      libavcodec   53.  7. 0 / 53.  7. 0
      libavformat  53.  4. 0 / 53.  4. 0
      libavdevice  53.  1. 1 / 53.  1. 1
      libavfilter   2. 23. 0 /  2. 23. 0
      libswscale    2.  0. 0 /  2.  0. 0
      libpostproc  51.  2. 0 / 51.  2. 0
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test_f4v.mp4':
      Metadata:
        major_brand     : f4v 
        minor_version   : 0
        compatible_brands: isommp42m4v 
        creation_time   : 2012-04-23 12:36:06
      Duration: 01:00:01.84, start: 0.000000, bitrate: 2004 kb/s
        Stream #0.0(eng): Video: h264 (Baseline), yuv420p, 854x480 [PAR 1:1 DAR 427:240], 1903 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
        Metadata:
          creation_time   : 2012-04-23 12:36:06
        Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 96 kb/s
        Metadata:
          creation_time   : 2012-04-23 12:36:06
    

    Now there is a problem. I need a file, which has the following meta data:

    major_brand     : mp42
    compatible_brands: isom
    

    Is there a way to remux the mp4 file to get the major_brand and compatible_brands to the described values with ffmpeg?

  • look for an mp4 file inside a directory and send it to different directory after converting to mp3 in php ?

    13 mai 2019, par flash

    I have a directory called incoming_folder in which there is an mp4 file.

    What I want to achieve through php code is to scan a incoming_folder directory, look for an mp4 file and send it to outgoing_folder after converting it into mp3. Technically outgoing_folder should have mp3 version of mp4 from incoming_folder

    Tried with the following code although its scanning the incoming_folder directory but no conversion is happening through ffmpeg.

    <?php
    $dir    = 'in_folder';  /* Place where mp4 file is present */
    $files1 = scandir($dir);
    print_r($files1);    /* It lists all the files in a directory including mp4 file*/
    
    $destination = 'out_folder';  /* Place where mp3 file need to be send after conversion from mp4 */
    
    foreach($files1 as $f)
    {
      $parts = pathinfo($f);
    
      switch($parts['extension'])
      {
        case 'mp4' :
          system('ffmpeg -i '.$f.' -map 0:2 -ac 1 '.$destination.DS. $parts['filename'].'.mp3', $result);
    
          if ($result) {
            // Do something with result if you want
            // log for example
          }
          break;
    
        case 'mp3' :
          // copy($f, $destination. DS . $parts['filename']. '.' . $parts['extension']);
          copy($f, $destination.DS.$parts['filename'].'.mp3');
          break;  
      }
    }
    ?>
    
  • Why does ffmpeg with libfdk_aac encoding cuts away 25ms in the beginning of an audio file ?

    13 mai 2019, par vkuzma

    I switched encoding from aac to libfdk_aac due to qaulity issues. I noticed with the new encoding a small part of the audio file will be cut in the beginning. I tested this with multiple files. This is the command i am using:

    ffmpeg -y -noaccurate_seek -i file.mp3 -b:a 260k -c:a libfdk_aac -vn -movflags +faststart output.m4a
    

    I tried different variations but alway ended up with cut file.

    Here is the output of a wave editor

    source file:

    enter image description here

    ouput:

    enter image description here

  • FFMpeg : how to use between() to select last second ?

    13 mai 2019, par rcpinheiro

    I'm trying to apply a caption using drawtext that should disappear one second before the video end:

    ffmpeg -i input.mp4 -vf "drawtext=enable='between(t,0,5)':fontfile=font.ttf:text='Some caption':x=60:y=640:fontsize=40:fontcolor=#f0f0f0@0.9" -vcodec libx264 -crf 27 -preset ultrafast -strict -2 -acodec copy output.mp4
    

    The problem is that I don't know the video length beforehand. I've tried using 'between(t,0,-1)' but it doesn't work, the caption never shows up. Anyone knows if is there a way to do this without having to open the video first to check length and only after that draw the caption? Thanks in advance!

  • Capture desktop with gdigrab and save the result to video file using ffmpeg and C++

    13 mai 2019, par Skunz

    I'm building a C++ application that is able to capture the screen and save the output to a file (.mkv, .mp4, doesn't matter).

    I tried to switch codecs and played with the AVCodecContext settings. When subsitute the gdi capture with reading from a static .mp4 file everything works fine.

    Here is my gdigrab initalization.

    _inputFormat = av_find_input_format("gdigrab");
    
        if (!_inputFormat) {
            std::cout << "Unable to open input Format" << std::endl;
            exit(1);
        }
    
        if (avformat_open_input(&_screenFormatContext, "desktop", _inputFormat, &_recordOptions) < 0) {
            std::cout << "Unable to open input stream" << std::endl;
            exit(1);
        }
    
        if (avformat_find_stream_info(_screenFormatContext, &_recordOptions) < 0) {
            std::cout << "Couldn't find input stream" << std::endl;
            exit(1);
        }
    
        av_dump_format(_screenFormatContext, 0, "GDI Capture", 0);
        for (int i = 0; i < _screenFormatContext->nb_streams; i++) {
            if (_screenFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                _videoStreamIdx = i;
                break;
            }
        }
    
        if (_videoStreamIdx == -1) {
            std::cout << "Unable to find video Stream" << std::endl;
            exit(1);
        }
    
        _codecPar = _screenFormatContext->streams[_videoStreamIdx]->codecpar;
    

    Here is my setup code for the encoder and decoder.

        /*
            Decoder
        */
        _dCodec = avcodec_find_decoder(_codecPar->codec_id);
        if (!_dCodec) {
            std::cout << "Unable to find decoder" << std::endl;
            exit(1);
        }
    
        _dCodecContext = avcodec_alloc_context3(_dCodec);
        if (avcodec_parameters_to_context(_dCodecContext, _codecPar) < 0) {
            std::cout << "Unable to copy context" << std::endl;
            exit(1);
        }
        if (avcodec_open2(_dCodecContext, _dCodec, NULL) < 0) {
            std::cout << "Unable to open dCodec" << std::endl;
            exit(1);
        }
    
        /*
            Encoder
        */
        _eCodec = avcodec_find_encoder(AV_CODEC_ID_H265);
        if (!_eCodec) {
            std::cout << "Unable to find encoder" << std::endl;
            exit(1);
        }
    
        _eCodecContext = avcodec_alloc_context3(_eCodec);
    
        //width and height have to be divisible by 2
        if (_codecPar->width % 2 != 0)
            _codecPar->width--;
        if (_codecPar->height % 2 != 0)
            _codecPar->height--;
    
        _eCodecContext->pix_fmt = AV_PIX_FMT_YUV422P;
        _eCodecContext->width = _codecPar->width;
        _eCodecContext->height = _codecPar->height;
        _eCodecContext->gop_size = 10;
        _eCodecContext->max_b_frames = 1;
    
        _eCodecContext->time_base.den = 30;
        _eCodecContext->time_base.num = 1;
    
        if (avcodec_open2(_eCodecContext, _eCodec, NULL) < 0) {
            std::cout << "Unable to open eCodec" << std::endl;
            exit(1);
        }
    

    Here is my main loop. Grabbing the packets from gdi, decoding them and encoding them.

        while (av_read_frame(_screenFormatContext, _pkt) == 0) {
            if (_pkt->stream_index == _videoStreamIdx) {
                if (_decodePacket() < 0)
                    exit(1);
                _encodeFrame();
            }
            av_packet_unref(_pkt);
    }
    
    

    And here the encoding/decoding functions

    int     ScreenRecorder::_decodePacket(void)
    {
        //send packet to decoder
        int ret = avcodec_send_packet(_dCodecContext, _pkt);
        if (ret < 0) {
            std::cout << "error while sending packet to decoder" << std::endl;
            return ret;
        }
    
        ret = avcodec_receive_frame(_dCodecContext, _frame);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            return 0;
        //Was there an error?
        else if (ret < 0) {
            std::cout << "Error with receiving frame" << std::endl;
            exit(1);
        }
        //No errors -> got frame
        std::cout << "Got frame " << _dCodecContext->frame_number << " with size " << _frame->pkt_size << std::endl;
        char frame_filename[1024];
        snprintf(frame_filename, sizeof(frame_filename), "%s-%d.pgm", "frame", _dCodecContext->frame_number);
        //_saveGrayFrame(_frame->data[0], _frame->linesize[0], _frame->width, _frame->height, frame_filename);
        return 0;
    }
    
    void    ScreenRecorder::_encodeFrame(void)
    {
        AVPacket* pkt = av_packet_alloc();
    
        // send frame to encoder - 0 on success
        int ret = avcodec_send_frame(_eCodecContext, _frame);
        if (ret < 0) {
            std::cerr << "Unable to send frame! ERRORCODE: " << ret << std::endl;
            exit(1);
        }
    
        while (ret == 0) {
            ret = avcodec_receive_packet(_eCodecContext, pkt);
            //Do I need to send more packets?
            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                std::cout << "Needing one more packet " << std::endl;
                av_packet_unref(pkt);
                return ;
            }
            //Was there an error?
            else if (ret < 0) {
                std::cout << "Error with receiving packet" << std::endl;
                exit(1);
            }
            //No errors -> got packet
            std::cout << "Got packet " << pkt->pts << " of size " << pkt->size << std::endl;
            if (av_write_frame(_outFormatContext, pkt) < 0) {
                std::cout << "Unable to write frame" << std::endl;
                exit(1);
            }
            av_packet_unref(pkt);
        }
    }
    

    In case you still need the header file

    #ifndef SCREENRECORDER_HPP
    # define SCREENRECORDER_HPP
    
    extern "C" {
        #include "libavcodec/avcodec.h"
        #include "libavdevice/avdevice.h"
        #include "libavformat/avformat.h"
        #include "libavformat/avio.h"
    }
    
    class ScreenRecorder
    {
    private:
        AVCodecContext      *_dCodecContext;
        AVCodecContext      *_eCodecContext;
    
        AVFormatContext     *_fileFormatContext;
        AVFormatContext     *_screenFormatContext;
        AVFormatContext     *_outFormatContext;
    
        AVInputFormat       *_inputFormat;
    
        AVCodecParameters   *_codecPar;
    
        AVStream            *_videoTrack;
    
        AVCodec             *_dCodec;
        AVCodec             *_eCodec;
    
        AVFrame             *_frame;
    
        AVPacket            *_pkt;
    
        AVDictionary        *_options;
        AVDictionary        *_recordOptions;
    
    
        int                 _videoStreamIdx;
    
        int                 _decodePacket(void);
        void                _encodeFrame(void);
        void                _openInputFile(void);
        void                _initalizeCodec(void);
        void                _initalizeOutputFile(void);
        void                _closeCodec(void);
        void                _initalizeGDI(void);
        void                _saveGrayFrame(unsigned char* buf, int wrap, int xsize, int ysize, char* filename);
    
    public:
        ScreenRecorder();
        ~ScreenRecorder();
    
        void                start();
    };
    
    #endif
    
    

    When I run my code I am getting Exception thrown at 0x00007FF819864A80 (msvcrt.dll) in Streaming.exe: 0xC0000005: Access violation reading location 0x0000000000000EF0. It comes from avcodec_send_frame function. Seems like I'm trying to access memory that wasn't allocated. I am new to the ffmpeg lib and hope that someone can get me on the right track. Thank you very much. If you have any questions please ask them.