Newest 'ffmpeg' Questions - Stack Overflow

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

Les articles publiés sur le site

  • No such filter in ffmpeg

    10 mars, par sneha desai

    I am trying to create the slideshow with below command.

    Here is the command I have executed:

     ffmpeg
    -loop 1 -t 1 -i /sdcard/input0.png 
    -loop 1 -t 1 -i /sdcard/input1.png 
    -loop 1 -t 1 -i /sdcard/input2.png 
    -loop 1 -t 1 -i /sdcard/input3.png 
    -loop 1 -t 1 -i /sdcard/input4.png 
    -filter_complex 
    "[0:v]trim=duration=15,fade=t=out:st=14.5:d=0.5[v0]; 
     [1:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v1]; 
     [2:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v2]; 
     [3:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v3]; 
     [4:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v4]; 
     [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" /sdcard/out.mp4
    

    on execution of this command it gives error something like:

     onFailure: ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers
      built with gcc 4.8 (GCC)
      configuration: --target-os=linux --cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-fontconfig --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-ffprobe --enable-gpl --enable-yasm --disable-doc --disable-shared --enable-static --pkg-config=/home/vagrant/SourceCode/ffmpeg-android/ffmpeg-pkg-config --prefix=/home/vagrant/SourceCode/ffmpeg-android/build/armeabi-v7a --extra-cflags='-I/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags='-L/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-libs='-lpng -lexpat -lm' --extra-cxxflags=
      libavutil      55. 17.103 / 55. 17.103
      libavcodec     57. 24.102 / 57. 24.102
      libavformat    57. 25.100 / 57. 25.100
      libavdevice    57.  0.101 / 57.  0.101
      libavfilter     6. 31.100 /  6. 31.100
      libswscale      4.  0.100 /  4.  0.100
      libswresample   2.  0.101 /  2.  0.101
      libpostproc    54.  0.100 / 54.  0.100
    [mjpeg @ 0x4362af10] Changing bps to 8
    Input #0, image2, from '/sdcard/img0001.jpg':
      Duration: 00:00:00.04, start: 0.000000, bitrate: 2410 kb/s
        Stream #0:0: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 259x194 [SAR 1:1 DAR 259:194], 25 fps, 25 tbr, 25 tbn, 25 tbc
    [mjpeg @ 0x436300a0] Changing bps to 8
    Input #1, image2, from '/sdcard/img0002.jpg':
      Duration: 00:00:00.04, start: 0.000000, bitrate: 2053 kb/s
        Stream #1:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 290x174 [SAR 1:1 DAR 5:3], 25 fps, 25 tbr, 25 tbn, 25 tbc
    [mjpeg @ 0x436383a0] Changing bps to 8
    Input #2, image2, from '/sdcard/img0003.jpg':
      Duration: 00:00:00.04, start: 0.000000, bitrate: 3791 kb/s
        Stream #2:0: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 300x168 [SAR 1:1 DAR 25:14], 25 fps, 25 tbr, 25 tbn, 25 tbc
    [mjpeg @ 0x43648f50] Changing bps to 8
    Input #3, image2, from '/sdcard/img0004.jpg':
      Duration: 00:00:00.04, start: 0.000000, bitrate: 1796 kb/s
        Stream #3:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 259x194 [SAR 1:1 DAR 259:194], 25 fps, 25 tbr, 25 tbn, 25 tbc
    [mjpeg @ 0x437b4070] Changing bps to 8
    Input #4, image2, from '/sdcard/img0005.jpg':
      Duration: 00:00:00.04, start: 0.000000, bitrate: 1083 kb/s
        Stream #4:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 212x160 [SAR 1:1 DAR 53:40], 25 fps, 25 tbr, 25 tbn, 25 tbc
    [AVFilterGraph @ 0x4393c960] No such filter: '"'
    Error initializing complex filters.
    Invalid argument
    

    and i used this demo https://github.com/WritingMinds/ffmpeg-android-java

  • ffmpeg arguments for youtube upload [duplicate]

    9 mars, par Hoopes

    I'm currently having an issue in my ios app where youtube sharing of a video created by ffmpeg seems broken. I am starting with an audio file, and an image that I will use as the static background of the video.

    ffmpeg -y 
    -i "/path/to/audio.m4a" 
    -r 24 
    -i "/path/to/background.png" 
    -codec:a aac_at 
    -codec:v h264_videotoolbox 
    -brand mp42 
    -vf "scale=1080:1080" 
    -vf "scale=out_color_matrix=bt709" 
    -color_primaries bt709 
    -color_trc bt709 
    -colorspace bt709 
    -movflags +faststart 
    "output.mp4"
    

    Note that since i'm on an ios device, i am using h264_videotoolbox, which uses the apple hardware to help encode it.

    When I use the regular ios share screen, and share to something like slack, the video seems to work fine. However, when I try to share to youtube via the same share screen, it looks like it can't detect the duration of the video:

    Youtube detecting zero duration

    Another thing to note is that when i download the file, and upload it to youtube via regular web browser, it seems to be fine - which somewhat points to it not being ffmpeg related, but it shares fine to other apps.

    I'm using ffmpeg version 5.1.2

  • Decoding and playing audio with ffmpeg and XAudio2 - frequency ratio wrong

    9 mars, par Brent de Carteret

    I'm using ffmpeg to decode audio and output it using the XAudio2 API, it works and plays synced with the video output using the pts. But it's high pitched (i.e. sounds like chipmunks).

    Setting breakpoints I can see it has set the correct sample rate from the audio codec in CreateSourceVoice. I'm stumped.

    Any help would be much appreciated.

    CDVDAUDIO.cpp

    #include "DVDAudioDevice.h"
       
    HANDLE m_hBufferEndEvent;
    
    CDVDAudio::CDVDAudio()
    {
        m_pXAudio2 = NULL;
        m_pMasteringVoice = NULL;
        m_pSourceVoice = NULL;
        m_pWfx  = NULL;
        m_VoiceCallback = NULL;    
        m_hBufferEndEvent = CreateEvent(NULL, false, false, "Buffer end event");
    }
        
    CDVDAudio::~CDVDAudio()
    {
        m_pXAudio2 = NULL;
        m_pMasteringVoice = NULL;
        m_pSourceVoice = NULL;
        m_pWfx  = NULL;
        m_VoiceCallback = NULL;
        CloseHandle(m_hBufferEndEvent);
        m_hBufferEndEvent = NULL;
    }
        
    bool CDVDAudio::Create(int iChannels, int iBitrate, int iBitsPerSample, bool bPasstrough)
    {
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        HRESULT hr = XAudio2Create( &m_pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
        
        if (SUCCEEDED(hr))
        {
            m_pXAudio2->CreateMasteringVoice( &m_pMasteringVoice );
        }
        
        // Create source voice
        WAVEFORMATEXTENSIBLE wfx;
        memset(&wfx, 0, sizeof(WAVEFORMATEXTENSIBLE));
        
        wfx.Format.wFormatTag           = WAVE_FORMAT_PCM;
        wfx.Format.nSamplesPerSec       = iBitrate;//pFFMpegData->pAudioCodecCtx->sample_rate;//48000 by default
        wfx.Format.nChannels            = iChannels;//pFFMpegData->pAudioCodecCtx->channels;
        wfx.Format.wBitsPerSample       = 16;
        wfx.Format.nBlockAlign          = wfx.Format.nChannels*16/8;
        wfx.Format.nAvgBytesPerSec      = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
        wfx.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
        wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
        
        if(wfx.Format.nChannels == 1)
        {
            wfx.dwChannelMask = SPEAKER_MONO;
        }
        else if(wfx.Format.nChannels == 2)
        {
            wfx.dwChannelMask = SPEAKER_STEREO;
        }
        else if(wfx.Format.nChannels == 5)
        {
            wfx.dwChannelMask = SPEAKER_5POINT1;
        }
        
        wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
        
        unsigned int flags = 0;//XAUDIO2_VOICE_NOSRC;// | XAUDIO2_VOICE_NOPITCH;
            
        //Source voice
        m_VoiceCallback = new StreamingVoiceCallback(this);
        hr = m_pXAudio2->CreateSourceVoice(&m_pSourceVoice,(WAVEFORMATEX*)&wfx, 0 , 1.0f, m_VoiceCallback);
            
        if (!SUCCEEDED(hr))
            return false;
        
        // Start sound
        hr = m_pSourceVoice->Start(0);
        
        if(!SUCCEEDED(hr))
            return false;
        
        return true;
    }
        
    DWORD CDVDAudio::AddPackets(unsigned char* data, DWORD len)
    {  
        memset(&m_SoundBuffer,0,sizeof(XAUDIO2_BUFFER));
        m_SoundBuffer.AudioBytes = len;
        m_SoundBuffer.pAudioData = data;
        m_SoundBuffer.pContext = NULL;//(VOID*)data;
        XAUDIO2_VOICE_STATE state;
        
        while (m_pSourceVoice->GetState( &state ), state.BuffersQueued > 60)
        {
            WaitForSingleObject( m_hBufferEndEvent, INFINITE );
        }
        
        m_pSourceVoice->SubmitSourceBuffer( &m_SoundBuffer );
        return 0;
    }
        
    void CDVDAudio::Destroy()
    {
        m_pMasteringVoice->DestroyVoice();
        m_pXAudio2->Release();
        m_pSourceVoice->DestroyVoice();
        delete m_VoiceCallback;
        m_VoiceCallback = NULL;
    }
    

    CDVDAUdioCodecFFmpeg.cpp

    #include "DVDAudioCodecFFmpeg.h"
    #include "Log.h"
        
    CDVDAudioCodecFFmpeg::CDVDAudioCodecFFmpeg() : CDVDAudioCodec()
    {
        m_iBufferSize = 0;
        m_pCodecContext = NULL;
        m_bOpenedCodec = false;
    }
        
    CDVDAudioCodecFFmpeg::~CDVDAudioCodecFFmpeg()
    {
        Dispose();
    }
        
    bool CDVDAudioCodecFFmpeg::Open(AVCodecID codecID, int iChannels, int iSampleRate)
    {
        AVCodec* pCodec;
        m_bOpenedCodec = false;
        av_register_all();
        pCodec = avcodec_find_decoder(codecID);
        m_pCodecContext = avcodec_alloc_context3(pCodec);//avcodec_alloc_context();
        avcodec_get_context_defaults3(m_pCodecContext, pCodec);
        
        if (!pCodec)
        {
            CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Open() Unable to find codec");
            return false;
        }
        
        m_pCodecContext->debug_mv = 0;
        m_pCodecContext->debug = 0;
        m_pCodecContext->workaround_bugs = 1;
        
        if (pCodec->capabilities & CODEC_CAP_TRUNCATED)
            m_pCodecContext->flags |= CODEC_FLAG_TRUNCATED;
        
        m_pCodecContext->channels = iChannels;
        m_pCodecContext->sample_rate = iSampleRate;
        //m_pCodecContext->bits_per_sample = 24;
         
        /* //FIXME BRENT
            if( ExtraData && ExtraSize > 0 )
            {
                m_pCodecContext->extradata_size = ExtraSize;
                m_pCodecContext->extradata = m_dllAvCodec.av_mallocz(ExtraSize + FF_INPUT_BUFFER_PADDING_SIZE);
                memcpy(m_pCodecContext->extradata, ExtraData, ExtraSize);
            }
        */
        
        // set acceleration
        //m_pCodecContext->dsp_mask = FF_MM_FORCE | FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE; //BRENT
        
        if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
        {
            CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Open() Unable to open codec");
            Dispose();
            return false;
        }
        
        m_bOpenedCodec = true;
        return true;
    }
        
    void CDVDAudioCodecFFmpeg::Dispose()
    {
        if (m_pCodecContext)
        {
            if (m_bOpenedCodec)
                avcodec_close(m_pCodecContext);
            m_bOpenedCodec = false;
            av_free(m_pCodecContext);
            m_pCodecContext = NULL;
        }
        m_iBufferSize = 0;
    }
    
    int CDVDAudioCodecFFmpeg::Decode(BYTE* pData, int iSize)
    {
        int iBytesUsed;
        if (!m_pCodecContext) return -1;
        
        //Copy into a FFMpeg AVPAcket again
        AVPacket packet;
        av_init_packet(&packet);
        
        packet.data=pData;
        packet.size=iSize;
        
        int iOutputSize = AVCODEC_MAX_AUDIO_FRAME_SIZE; //BRENT
        
        iBytesUsed = avcodec_decode_audio3(m_pCodecContext, (int16_t *)m_buffer, &iOutputSize/*m_iBufferSize*/, &packet);
    
        m_iBufferSize = iOutputSize;//BRENT
    
        return iBytesUsed;
    }
    
    int CDVDAudioCodecFFmpeg::GetData(BYTE** dst)
    {
        *dst = m_buffer;
        return m_iBufferSize;
    }
    
    void CDVDAudioCodecFFmpeg::Reset()
    {
        if (m_pCodecContext)
            avcodec_flush_buffers(m_pCodecContext);
    }
    
    int CDVDAudioCodecFFmpeg::GetChannels()
    {
        if (m_pCodecContext)
            return m_pCodecContext->channels;
        return 0;
    }
    
    int CDVDAudioCodecFFmpeg::GetSampleRate()
    {
        if (m_pCodecContext)
            return m_pCodecContext->sample_rate;
        return 0;
    }
        
    int CDVDAudioCodecFFmpeg::GetBitsPerSample()
    {
        if (m_pCodecContext)
            return 16;
        return 0;
    }
    

    CDVDPlayerAudio.cpp

    #include "DVDPlayerAudio.h"
    #include "DVDDemuxUtils.h"
    #include "Log.h"
        
    #include 
    #include "DVDAudioCodecFFmpeg.h" //FIXME Move to a codec factory!!
        
    CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock) : CThread()
    {
        m_pClock = pClock;
        m_pAudioCodec = NULL;
        m_bInitializedOutputDevice = false;
        m_iSourceChannels = 0;
        m_audioClock = 0;
        
        //  m_currentPTSItem.pts = DVD_NOPTS_VALUE;
        //  m_currentPTSItem.timestamp = 0;
        
        SetSpeed(DVD_PLAYSPEED_NORMAL);
          
        InitializeCriticalSection(&m_critCodecSection);
        m_messageQueue.SetMaxDataSize(10 * 16 * 1024);
        //  g_dvdPerformanceCounter.EnableAudioQueue(&m_packetQueue);
    }
    
    CDVDPlayerAudio::~CDVDPlayerAudio()
    {
        //  g_dvdPerformanceCounter.DisableAudioQueue();
    
        // close the stream, and don't wait for the audio to be finished
        CloseStream(true);
        DeleteCriticalSection(&m_critCodecSection);
    }
    
    bool CDVDPlayerAudio::OpenStream( CDemuxStreamAudio *pDemuxStream )
    {
        // should always be NULL!!!!, it will probably crash anyway when deleting m_pAudioCodec here.
        if (m_pAudioCodec)
        {
            CLog::Log(LOGFATAL, "CDVDPlayerAudio::OpenStream() m_pAudioCodec != NULL");
            return false;
        }
        
        AVCodecID codecID = pDemuxStream->codec;
        
        CLog::Log(LOGNOTICE, "Finding audio codec for: %i", codecID);
        //m_pAudioCodec = CDVDFactoryCodec::CreateAudioCodec( pDemuxStream ); 
        m_pAudioCodec = new CDVDAudioCodecFFmpeg; //FIXME BRENT Codec Factory needed!
        
        if (!m_pAudioCodec->Open(pDemuxStream->codec, pDemuxStream->iChannels, pDemuxStream->iSampleRate))
        {
            m_pAudioCodec->Dispose();
            delete m_pAudioCodec;
            m_pAudioCodec = NULL;
            return false;
        }
        
        if ( !m_pAudioCodec )
        {
            CLog::Log(LOGERROR, "Unsupported audio codec");
            return false;
        }
        
        m_codec = pDemuxStream->codec;
        m_iSourceChannels = pDemuxStream->iChannels;
        m_messageQueue.Init();
        
        CLog::Log(LOGNOTICE, "Creating audio thread");
        Create();
        
        return true;
    }
    
    void CDVDPlayerAudio::CloseStream(bool bWaitForBuffers)
    {
        // wait until buffers are empty
        if (bWaitForBuffers)
            m_messageQueue.WaitUntilEmpty();
        
        // send abort message to the audio queue
        m_messageQueue.Abort();
        
        CLog::Log(LOGNOTICE, "waiting for audio thread to exit");
        
        // shut down the audio_decode thread and wait for it
        StopThread(); // will set this->m_bStop to true
        this->WaitForThreadExit(INFINITE);
        
        // uninit queue
        m_messageQueue.End();
        
        CLog::Log(LOGNOTICE, "Deleting audio codec");
        if (m_pAudioCodec)
        {
            m_pAudioCodec->Dispose();
            delete m_pAudioCodec;
            m_pAudioCodec = NULL;
        }
        
        // flush any remaining pts values
        //FlushPTSQueue(); //FIXME BRENT
    }
    
    void CDVDPlayerAudio::OnStartup()
    {
        CThread::SetName("CDVDPlayerAudio");
        pAudioPacket = NULL;
        m_audioClock = 0;
        audio_pkt_data = NULL;
        audio_pkt_size = 0;
      
        //  g_dvdPerformanceCounter.EnableAudioDecodePerformance(ThreadHandle());
    }
    
    void CDVDPlayerAudio::Process()
    {
        CLog::Log(LOGNOTICE, "running thread: CDVDPlayerAudio::Process()");
    
        int result;
        
        // silence data
        BYTE silence[1024];
        memset(silence, 0, 1024);
        
        DVDAudioFrame audioframe;
        
        __int64 iClockDiff=0;
        while (!m_bStop)
        {
            //Don't let anybody mess with our global variables
            EnterCriticalSection(&m_critCodecSection);
            result = DecodeFrame(audioframe, m_speed != DVD_PLAYSPEED_NORMAL); // blocks if no audio is available, but leaves critical section before doing so
            LeaveCriticalSection(&m_critCodecSection);
        
            if ( result & DECODE_FLAG_ERROR ) 
            {      
                CLog::Log(LOGERROR, "CDVDPlayerAudio::Process - Decode Error. Skipping audio frame");
                continue;
            }
        
            if ( result & DECODE_FLAG_ABORT )
            {
                CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Abort received, exiting thread");
                break;
            }
        
            if ( result & DECODE_FLAG_DROP ) //FIXME BRENT
            {
                /*  //frame should be dropped. Don't let audio move ahead of the current time thou
                    //we need to be able to start playing at any time
                    //when playing backwards, we try to keep as small buffers as possible
        
                    // set the time at this delay
                    AddPTSQueue(audioframe.pts, m_dvdAudio.GetDelay());
                */
                if (m_speed > 0)
                {
                    __int64 timestamp = m_pClock->GetAbsoluteClock() + (audioframe.duration * DVD_PLAYSPEED_NORMAL) / m_speed;
                    while ( !m_bStop && timestamp > m_pClock->GetAbsoluteClock() )
                        Sleep(1);
                }
                continue;
            }
        
            if ( audioframe.size > 0 ) 
            {
                // we have successfully decoded an audio frame, open up the audio device if not already done
                if (!m_bInitializedOutputDevice)
                {
                    m_bInitializedOutputDevice = InitializeOutputDevice();
                }
        
                //Add any packets play
                m_dvdAudio.AddPackets(audioframe.data, audioframe.size);
        
                // store the delay for this pts value so we can calculate the current playing
                //AddPTSQueue(audioframe.pts, m_dvdAudio.GetDelay() - audioframe.duration);//BRENT
            }
        
            // if we where asked to resync on this packet, do so here
            if ( result & DECODE_FLAG_RESYNC )
            {
                CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Resync recieved.");
                //while (!m_bStop && (unsigned int)m_dvdAudio.GetDelay() > audioframe.duration ) Sleep(5); //BRENT
                m_pClock->Discontinuity(CLOCK_DISC_NORMAL, audioframe.pts);
            }
        
            #ifdef USEOLDSYNC
            //Clock should be calculated after packets have been added as m_audioClock points to the 
            //time after they have been played
        
            const __int64 iCurrDiff = (m_audioClock - m_dvdAudio.GetDelay()) - m_pClock->GetClock();
            const __int64 iAvDiff = (iClockDiff + iCurrDiff)/2;
        
            //Check for discontinuity in the stream, use a moving average to
            //eliminate highfreq fluctuations of large packet sizes
            if ( ABS(iAvDiff) > 5000 ) // sync clock if average diff is bigger than 5 msec 
            {
                //Wait until only the new audio frame which triggered the discontinuity is left
                //then set disc state
                while (!m_bStop && (unsigned int)m_dvdAudio.GetBytesInBuffer() > audioframe.size )
                    Sleep(5);
        
                m_pClock->Discontinuity(CLOCK_DISC_NORMAL, m_audioClock - m_dvdAudio.GetDelay());
                CLog::("CDVDPlayer:: Detected Audio Discontinuity, syncing clock. diff was: %I64d, %I64d, av: %I64d", iClockDiff, iCurrDiff, iAvDiff);
                iClockDiff = 0;
            }
            else
            {
                //Do gradual adjustments (not working yet)
                //m_pClock->AdjustSpeedToMatch(iClock + iAvDiff);
                iClockDiff = iCurrDiff;
            }
            #endif
        }
    }
    
    void CDVDPlayerAudio::OnExit()
    {
        //g_dvdPerformanceCounter.DisableAudioDecodePerformance();
      
        // destroy audio device
        CLog::Log(LOGNOTICE, "Closing audio device");
        m_dvdAudio.Destroy();
        m_bInitializedOutputDevice = false;
    
        CLog::Log(LOGNOTICE, "thread end: CDVDPlayerAudio::OnExit()");
    }
    
    // decode one audio frame and returns its uncompressed size
    int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
    {
        CDVDDemux::DemuxPacket* pPacket = pAudioPacket;
        int n=48000*2*16/8, len;
        
        //Store amount left at this point, and what last pts was
        unsigned __int64 first_pkt_pts = 0;
        int first_pkt_size = 0; 
        int first_pkt_used = 0;
        int result = 0;
        
        // make sure the sent frame is clean
        memset(&audioframe, 0, sizeof(DVDAudioFrame));
        
        if (pPacket)
        {
            first_pkt_pts = pPacket->pts;
            first_pkt_size = pPacket->iSize;
            first_pkt_used = first_pkt_size - audio_pkt_size;
        }
         
        for (;;)
        {
            /* NOTE: the audio packet can contain several frames */
            while (audio_pkt_size > 0)
            {
                len = m_pAudioCodec->Decode(audio_pkt_data, audio_pkt_size);
                if (len < 0)
                {
                    /* if error, we skip the frame */
                    audio_pkt_size=0;
                    m_pAudioCodec->Reset();
                    break;
                }
        
                // fix for fucked up decoders //FIXME BRENT
                if( len > audio_pkt_size )
                {        
                    CLog::Log(LOGERROR, "CDVDPlayerAudio:DecodeFrame - Codec tried to consume more data than available. Potential memory corruption");        
                    audio_pkt_size=0;
                    m_pAudioCodec->Reset();
                    assert(0);
                }
        
                // get decoded data and the size of it
                audioframe.size = m_pAudioCodec->GetData(&audioframe.data);
                audio_pkt_data += len;
                audio_pkt_size -= len;
        
                if (audioframe.size <= 0)
                    continue;
        
                audioframe.pts = m_audioClock;
        
                // compute duration.
                n = m_pAudioCodec->GetChannels() * m_pAudioCodec->GetBitsPerSample() / 8 * m_pAudioCodec->GetSampleRate();
                if (n > 0)
                {
                    // safety check, if channels == 0, n will result in 0, and that will result in a nice divide exception
                    audioframe.duration = (unsigned int)(((__int64)audioframe.size * DVD_TIME_BASE) / n);
        
                    // increase audioclock to after the packet
                    m_audioClock += audioframe.duration;
                }
        
                //If we are asked to drop this packet, return a size of zero. then it won't be played
                //we currently still decode the audio.. this is needed since we still need to know it's 
                //duration to make sure clock is updated correctly.
                if ( bDropPacket )
                {
                    result |= DECODE_FLAG_DROP;
                }
                return result;
            }
        
            // free the current packet
            if (pPacket)
            {
                CDVDDemuxUtils::FreeDemuxPacket(pPacket); //BRENT FIXME
                pPacket = NULL;
                pAudioPacket = NULL;
            }
        
            if (m_messageQueue.RecievedAbortRequest())
                return DECODE_FLAG_ABORT;
        
            // read next packet and return -1 on error
            LeaveCriticalSection(&m_critCodecSection); //Leave here as this might stall a while
        
            CDVDMsg* pMsg;
            MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, INFINITE);
            EnterCriticalSection(&m_critCodecSection);
                
            if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT)
                return DECODE_FLAG_ABORT;
        
            if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))
            {
                CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg;
                pPacket = pMsgDemuxerPacket->GetPacket();
                pMsgDemuxerPacket->m_pPacket = NULL; // XXX, test
                pAudioPacket = pPacket;
                audio_pkt_data = pPacket->pData;
                audio_pkt_size = pPacket->iSize;
            }
            else
            {
                // other data is not used here, free if
                // msg itself will still be available
                pMsg->Release();
            }
     
            // if update the audio clock with the pts
            if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET) || pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
            {
                if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
                { 
                    //player asked us to sync on this package
                    CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg;
                    result |= DECODE_FLAG_RESYNC;
                    m_audioClock = pMsgGeneralResync->GetPts();
                }
                else if (pPacket->pts != DVD_NOPTS_VALUE) // CDVDMsg::DEMUXER_PACKET, pPacket is already set above
                {
                    if (first_pkt_size == 0) 
                    { 
                        //first package
                        m_audioClock = pPacket->pts;        
                    }
                    else if (first_pkt_pts > pPacket->pts)
                    { 
                        //okey first packet in this continous stream, make sure we use the time here        
                        m_audioClock = pPacket->pts;        
                    }
                    else if ((unsigned __int64)m_audioClock < pPacket->pts || (unsigned __int64)m_audioClock > pPacket->pts)
                    {
                        //crap, moved outsided correct pts
                        //Use pts from current packet, untill we find a better value for it.
                        //Should be ok after a couple of frames, as soon as it starts clean on a packet
                        m_audioClock = pPacket->pts;
                    }
                    else if (first_pkt_size == first_pkt_used)
                    {
                        //Nice starting up freshly on the start of a packet, use pts from it
                        m_audioClock = pPacket->pts;
                    }
                }
            }
            pMsg->Release();
        }
    }
    
    void CDVDPlayerAudio::SetSpeed(int speed)
    { 
        m_speed = speed;
      
        //if (m_speed == DVD_PLAYSPEED_PAUSE) m_dvdAudio.Pause(); //BRENT FIXME
        //else m_dvdAudio.Resume();
    }
        
    bool CDVDPlayerAudio::InitializeOutputDevice()
    {
        int iChannels = m_pAudioCodec->GetChannels();
        int iSampleRate = m_pAudioCodec->GetSampleRate();
        int iBitsPerSample = m_pAudioCodec->GetBitsPerSample();
        //bool bPasstrough = m_pAudioCodec->NeedPasstrough(); //BRENT
        
        if (iChannels == 0 || iSampleRate == 0 || iBitsPerSample == 0)
        {
            CLog::Log(LOGERROR, "Unable to create audio device, (iChannels == 0 || iSampleRate == 0 || iBitsPerSample == 0)");
            return false;
        }
        
        CLog::Log(LOGNOTICE, "Creating audio device with codec id: %i, channels: %i, sample rate: %i", m_codec, iChannels, iSampleRate);
        if (m_dvdAudio.Create(iChannels, iSampleRate, iBitsPerSample, /*bPasstrough*/0)) // always 16 bit with ffmpeg ? //BRENT Passthrough needed?
        {
            return true;
        }
        
        CLog::Log(LOGERROR, "Failed Creating audio device with codec id: %i, channels: %i, sample rate: %i", m_codec, iChannels, iSampleRate);
        return false;
    }
    
  • Can't import moviepy due to missing ffmpex.exe

    9 mars, par SilentGrove_99

    I was trying to create an application with python using the moviepy library. I installed it using:

    pip install moviepy
    

    I found this from a MoviePy crash-course:

    # Import everything needed to edit video clips
    from moviepy.editor import *
    # or 
    from moviepy import *  # moviepy v2 after removal of editor
    

    After trying to run this line i get this error:

    Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32     bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> # Import everything needed to edit video clips
    ... from moviepy.editor import *
    Traceback (most recent call last):
      File "", line 2, in 
      File "C:\Python27\lib\site-packages\moviepy\editor.py", line 22, in 
        from .video.io.VideoFileClip import VideoFileClip
      File "C:\Python27\lib\site-packages\moviepy\video\io\VideoFileClip.py", line 3, in 
        from moviepy.video.VideoClip import VideoClip
      File "C:\Python27\lib\site-packages\moviepy\video\VideoClip.py", line 20, in 
        from .io.ffmpeg_writer import ffmpeg_write_image, ffmpeg_write_video
      File "C:\Python27\lib\site-packages\moviepy\video\io\ffmpeg_writer.py", line 15, in 
        from moviepy.config import get_setting
      File "C:\Python27\lib\site-packages\moviepy\config.py", line 38, in 
        FFMPEG_BINARY = get_exe()
      File "C:\Python27\lib\site-packages\imageio\plugins\ffmpeg.py", line 86, in get_exe
        raise NeedDownloadError('Need ffmpeg exe. '
    imageio.core.fetching.NeedDownloadError: Need ffmpeg exe. You can download it by calling:
      imageio.plugins.ffmpeg.download()
    

    What is the problem here, and how can i fix it?

  • How to Capture a Sequence of High-Quality PDF Frames from a Website (Without Screen Recording) ?

    9 mars, par Pubg Mobile

    In Firefox, I can take very high-quality screenshots of a webpage by using Ctrl + P and saving the page as a PDF. This method preserves the text, images, and code in excellent resolution.

    Now, I have created a movable bar chart race in Flourish Studio and want to convert it into a high-quality video. However, I do not want to use screen recording tools.

    My Goal:
    I want to capture 30 high-resolution PDF frames from the website at different points in time (like a video sequence). Ideally, I need a tool or script that can automate the process of saving multiple PDFs from the website as it plays the animation.

    What I Tried:
    I attempted to write a Python script that:

    Opens the local HTML file of my Flourish chart in Firefox using Selenium.
    Waits for the page to load.
    Listens for the F1 key and triggers Ctrl + P to print the page as a PDF.
    However, the script does not save the PDF file in the output folder. I'm not sure why.

    Here is my code:

    import time
    import keyboard
    from selenium import webdriver
    from selenium.webdriver.firefox.service import Service
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.firefox.options import Options
    
    # Define paths
    html_file_path = r"E:\Desktop\New folder (4)\20250309101616805.html"
    geckodriver_path = r"E:\Desktop\New folder (4)\geckodriver.exe"
    save_path = r"E:\Desktop\New folder (4)\New folder\output.pdf"  # Save PDF location
    
    # Set up Firefox options
    options = Options()
    options.set_preference("print.always_print_silent", True)  # Silent printing
    options.set_preference("print.show_print_progress", False)  # Hide progress
    options.set_preference("print.print_to_file", True)  # Print to file
    options.set_preference("print.save_print_settings", True)  # Save settings
    options.set_preference("print.printer_PDF", "Save as PDF")  # Set printer
    options.set_preference("print.print_to_file", True)  # Enable saving print output to file
    options.set_preference("print.print_file_name", save_path)  # Define the save location for PDF
    
    # Start WebDriver
    service = Service(executable_path=geckodriver_path)
    driver = webdriver.Firefox(service=service, options=options)
    
    # Open the HTML file
    driver.get("file:///" + html_file_path)
    
    # Wait for the page to load
    time.sleep(2)
    
    print("Press F1 to save as PDF.")
    
    # Listen for F1 key press
    while True:
        if keyboard.is_pressed('F1'):
            print("F1 pressed, saving as PDF...")
            
            # Trigger print command (Ctrl + P)
            body = driver.find_element(By.TAG_NAME, 'body')
            body.send_keys(Keys.CONTROL + 'p')
            
            # Wait for the print dialog to process
            time.sleep(2)
    
            print("PDF should be saved to:", save_path)
            break
    
    # Close browser
    driver.quit()
    

    My Questions:

    Why is my script not saving the PDF in the specified output folder?

    Is there a better way to automate capturing 30 sequential PDFs from the website at different animation frames?

    Is there any tool or script that can generate a sequence of PDFs (like 30 frames per second) from a webpage?

    Important:

    I do NOT want to use screen recording tools.

    I only need high-quality PDF frames that can later be converted into a video.

    Any help would be greatly appreciated!