Newest 'ffmpeg' Questions - Stack Overflow

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

Les articles publiés sur le site

  • how to stream h.264 video with mp3 audio using libavcodec ?

    18 septembre 2012, par dasg

    I read h.264 frames from webcamera and capture audio from microphone. I need to stream live video to ffserver. During debug I read video from ffserver using ffmpeg with following command:

    ffmpeg -i http://127.0.0.1:12345/robot.avi -vcodec copy -acodec copy out.avi
    

    My video in output file is slightly accelerated. If I add a audio stream it is accelerated several times. Sometimes there is no audio in the output file.

    Here is my code for encoding audio:

    #include "v_audio_encoder.h"
    
    extern "C" {
    #include avcodec.h>
    }
    #include 
    
    struct VAudioEncoder::Private
    {
        AVCodec *m_codec;
        AVCodecContext *m_context;
    
        std::vector m_outBuffer;
    };
    
    VAudioEncoder::VAudioEncoder( int sampleRate, int bitRate )
    {
        d = new Private( );
        d->m_codec = avcodec_find_encoder( CODEC_ID_MP3 );
        assert( d->m_codec );
        d->m_context = avcodec_alloc_context3( d->m_codec );
    
        // put sample parameters
        d->m_context->channels = 2;
        d->m_context->bit_rate = bitRate;
        d->m_context->sample_rate = sampleRate;
        d->m_context->sample_fmt = AV_SAMPLE_FMT_S16;
        strcpy( d->m_context->codec_name, "libmp3lame" );
    
        // open it
        int res = avcodec_open2( d->m_context, d->m_codec, 0 );
        assert( res >= 0 );
    
        d->m_outBuffer.resize( d->m_context->frame_size );
    }
    
    VAudioEncoder::~VAudioEncoder( )
    {
        avcodec_close( d->m_context );
        av_free( d->m_context );
        delete d;
    }
    
    void VAudioEncoder::encode( const std::vector& samples, std::vector& outbuf )
    {
        assert( (int)samples.size( ) == d->m_context->frame_size );
    
        int outSize = avcodec_encode_audio( d->m_context, d->m_outBuffer.data( ),
                                            d->m_outBuffer.size( ), reinterpret_cast( samples.data( ) ) );
        if( outSize ) {
            outbuf.resize( outSize );
            memcpy( outbuf.data( ), d->m_outBuffer.data( ), outSize );
        }
        else
            outbuf.clear( );
    }
    
    int VAudioEncoder::getFrameSize( ) const
    {
        return d->m_context->frame_size;
    }
    

    Here is my code for streaming video:

    #include "v_out_video_stream.h"
    
    extern "C" {
    #include avformat.h>
    #include opt.h>
    #include avstring.h>
    #include avio.h>
    }
    
    #include 
    #include 
    
    struct VStatticRegistrar
    {
        VStatticRegistrar( )
        {
            av_register_all( );
            avformat_network_init( );
        }
    };
    
    VStatticRegistrar __registrar;
    
    struct VOutVideoStream::Private
    {
        AVFormatContext * m_context;
        int m_videoStreamIndex;
        int m_audioStreamIndex;
    
        int m_videoBitrate;
        int m_width;
        int m_height;
        int m_fps;
        int m_bitrate;
    
        bool m_waitKeyFrame;
    };
    
    VOutVideoStream::VOutVideoStream( int width, int height, int fps, int bitrate )
    {
        d = new Private( );
        d->m_width = width;
        d->m_height = height;
        d->m_fps = fps;
        d->m_context = 0;
        d->m_videoStreamIndex = -1;
        d->m_audioStreamIndex = -1;
        d->m_bitrate = bitrate;
        d->m_waitKeyFrame = true;
    }
    
    bool VOutVideoStream::connectToServer( const std::string& uri )
    {
        assert( ! d->m_context );
    
        // initalize the AV context
        d->m_context = avformat_alloc_context();
        if( !d->m_context )
            return false;
        // get the output format
        d->m_context->oformat = av_guess_format( "ffm", NULL, NULL );
        if( ! d->m_context->oformat )
            return false;
    
        strcpy( d->m_context->filename, uri.c_str( ) );
    
        // add an H.264 stream
        AVStream *stream = avformat_new_stream( d->m_context, NULL );
        if ( ! stream )
            return false;
        // initalize codec
        AVCodecContext* codec = stream->codec;
        if( d->m_context->oformat->flags & AVFMT_GLOBALHEADER )
            codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        codec->codec_id = CODEC_ID_H264;
        codec->codec_type = AVMEDIA_TYPE_VIDEO;
        strcpy( codec->codec_name, "libx264" );
    //    codec->codec_tag = ( unsigned('4') << 24 ) + (unsigned('6') << 16 ) + ( unsigned('2') << 8 ) + 'H';
        codec->width = d->m_width;
        codec->height = d->m_height;
        codec->time_base.den = d->m_fps;
        codec->time_base.num = 1;
        codec->bit_rate = d->m_bitrate;
        d->m_videoStreamIndex = stream->index;
    
        // add an MP3 stream
        stream = avformat_new_stream( d->m_context, NULL );
        if ( ! stream )
            return false;
        // initalize codec
        codec = stream->codec;
        if( d->m_context->oformat->flags & AVFMT_GLOBALHEADER )
            codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        codec->codec_id = CODEC_ID_MP3;
        codec->codec_type = AVMEDIA_TYPE_AUDIO;
        strcpy( codec->codec_name, "libmp3lame" );
        codec->sample_fmt = AV_SAMPLE_FMT_S16;
        codec->channels = 2;
        codec->bit_rate = 64000;
        codec->sample_rate = 44100;
        d->m_audioStreamIndex = stream->index;
    
        // try to open the stream
        if( avio_open( &d->m_context->pb, d->m_context->filename, AVIO_FLAG_WRITE ) < 0 )
             return false;
    
        // write the header
        return avformat_write_header( d->m_context, NULL ) == 0;
    }
    
    void VOutVideoStream::disconnect( )
    {
        assert( d->m_context );
    
        avio_close( d->m_context->pb );
        avformat_free_context( d->m_context );
        d->m_context = 0;
    }
    
    VOutVideoStream::~VOutVideoStream( )
    {
        if( d->m_context )
            disconnect( );
        delete d;
    }
    
    int VOutVideoStream::getVopType( const std::vector& image )
    {
        if( image.size( ) < 6 )
            return -1;
        unsigned char *b = (unsigned char*)image.data( );
    
        // Verify NAL marker
        if( b[ 0 ] || b[ 1 ] || 0x01 != b[ 2 ] ) {
            ++b;
            if ( b[ 0 ] || b[ 1 ] || 0x01 != b[ 2 ] )
                return -1;
        }
    
        b += 3;
    
        // Verify VOP id
        if( 0xb6 == *b ) {
            ++b;
            return ( *b & 0xc0 ) >> 6;
        }
    
        switch( *b ) {
        case 0x65: return 0;
        case 0x61: return 1;
        case 0x01: return 2;
        }
    
        return -1;
    }
    
    bool VOutVideoStream::sendVideoFrame( std::vector& image )
    {
        // Init packet
        AVPacket pkt;
        av_init_packet( &pkt );
        pkt.flags |= ( 0 >= getVopType( image ) ) ? AV_PKT_FLAG_KEY : 0;
    
        // Wait for key frame
        if ( d->m_waitKeyFrame ) {
            if( pkt.flags & AV_PKT_FLAG_KEY )
                d->m_waitKeyFrame = false;
            else
                return true;
        }
    
        pkt.stream_index = d->m_videoStreamIndex;
        pkt.data = image.data( );
        pkt.size = image.size( );
        pkt.pts = pkt.dts = AV_NOPTS_VALUE;
    
        return av_write_frame( d->m_context, &pkt ) >= 0;
    }
    
    bool VOutVideoStream::sendAudioFrame( std::vector& audio )
    {
        // Init packet
        AVPacket pkt;
        av_init_packet( &pkt );
        pkt.stream_index = d->m_audioStreamIndex;
        pkt.data = audio.data( );
        pkt.size = audio.size( );
        pkt.pts = pkt.dts = AV_NOPTS_VALUE;
    
        return av_write_frame( d->m_context, &pkt ) >= 0;
    }
    

    Here is how I use it:

    BOOST_AUTO_TEST_CASE(testSendingVideo)
    {
        const int framesToGrab = 90000;
    
        VOutVideoStream stream( VIDEO_WIDTH, VIDEO_HEIGHT, FPS, VIDEO_BITRATE );
        if( stream.connectToServer( URI ) ) {
            VAudioEncoder audioEncoder( AUDIO_SAMPLE_RATE, AUDIO_BIT_RATE );
            VAudioCapture microphone( MICROPHONE_NAME, AUDIO_SAMPLE_RATE, audioEncoder.getFrameSize( ) );
    
            VLogitecCamera camera( VIDEO_WIDTH, VIDEO_HEIGHT );
            BOOST_REQUIRE( camera.open( CAMERA_PORT ) );
            BOOST_REQUIRE( camera.startCapturing( ) );
    
            std::vector image, encodedAudio;
            std::vector voice;
            boost::system_time startTime;
            int delta;
            for( int i = 0; i < framesToGrab; ++i ) {
                startTime = boost::posix_time::microsec_clock::universal_time( );
    
                BOOST_REQUIRE( camera.read( image ) );
                BOOST_REQUIRE( microphone.read( voice ) );
                audioEncoder.encode( voice, encodedAudio );
    
                BOOST_REQUIRE( stream.sendVideoFrame( image ) );
                BOOST_REQUIRE( stream.sendAudioFrame( encodedAudio ) );
    
                delta = ( boost::posix_time::microsec_clock::universal_time( ) - startTime ).total_milliseconds( );
                if( delta < 1000 / FPS )
                    boost::thread::sleep( startTime + boost::posix_time::milliseconds( 1000 / FPS - delta ) );
            }
    
            BOOST_REQUIRE( camera.stopCapturing( ) );
            BOOST_REQUIRE( camera.close( ) );
        }
        else
            std::cout << "failed to connect to server" << std::endl;
    }
    

    I think my problem is in PTS and DTS. Can anyone help me?

  • Mass Watermark Videos with Different Formats/Dimensions Programmatically

    17 septembre 2012, par ColorWP.com

    Is there a way to programmatically (using PHP) convert a directory full of videos with all kinds of formats (avi, mp4, mpeg, wmv) with different dimensions to a single format output (e.g. mp4) with the same dimensions as the input video and with a custom image watermark at the same position over the video (e.g. bottom left). Preferably, without lowering video quality and without making the watermark too large or too small for the resolution (maybe relative size to the video dimensions?).

  • Get ffmpeg information in friendly way

    17 septembre 2012, par JBernardo

    Every time I try to get some information about my video files with ffmpeg, it pukes a lot of useless information mixed with good things.

    I'm using ffmpeg -i name_of_the_video.mpg.

    There are any possibilities to get that in a friendly way? I mean JSON would be great (and even ugly XML is fine).

    By now, I made my application parse the data with regex but there are lots of nasty corners that appear on some specific video files. I fixed all that I encountered, but there may be more.

    I wanted something like:

    {
      "Stream 0": {
         "type": "Video",
         "codec": "h264",
         "resolution": "720x480"
      },
      "Stream 1": {
         "type": "Audio",
         "bitrate": "128 kbps",
         "channels": 2
      }
    }
    
  • Getting exception while trying to run ffmpeg via command line in android

    17 septembre 2012, par user1662334

    I want to use ffmpeg via command line arguments in android application.For this purpose:

    1. I have cross-compiled the ffmpeg lib and got the libffmpeg.so
    2. I have stored libffmpeg.so in files directory of the app.

    This is the code i am using:

    public class MainActivity extends Activity {
    
        Process p;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
                String[] cmd =new String[4];
            cmd[0]="/data/data/com.example.ffmpegnew/files/libffmpeg";
            cmd[1]="-i";
            cmd[2]="mnt/sdcard/music/baba.mp4";
            cmd[3]="mnt/sdcard/music/outfile.mp4";
    
            p = Runtime.getRuntime().exec(cmd,null, new File("/data/data/com.example.ffmpegnew/files"));
    
            }
            catch(Exception e)
            {
                System.out.println("exception"+e);
            }
    
        }
    
    }
    

    This is the exception i am getting:

    09-17 13:47:01.679: I/System.out(3752): exceptionjava.io.IOException: Error running exec(). Command: [/data/data/com.example.ffmpegnew/files/libffmpeg.so, -i, mnt/sdcard/music/baba.mp4, mnt/sdcard/music/outfile.mp4] Working Directory: /data/data/com.example.ffmpegnew/files Environment: null
    

    Please tell me how to solve this problem.Thanks in advance.

  • Getting IO Exception while using Runtime.getRuntime().exec()

    16 septembre 2012, par user1662334

    I want to use command line facility in android to use ffmpeg library.But i am getting IO Exception while trying that,I have stored ffmpeg.exe in /files folder.This is the code:

    public class MainActivity extends Activity {
    
        Process p;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Process p = Runtime.getRuntime().exec("/data/data/com.example.ffmpegnew/files/ffmpeg",null, new File("/data/data/com.example.ffmpegnew/files"));
    
            }
            catch(Exception e)
            {
                System.out.println("exception"+e);
            }
    
        }
    
    }
    

    This is the error :

    09-16 16:24:38.751: I/System.out(2209): exceptionjava.io.IOException: Error running exec(). Commands: [/data/data/com.example.ffmpegnew] Working Directory: /data/data Environment: null
    

    Please tell me what is the problem.Thanks in advance.