Newest 'ffmpeg' Questions - Stack Overflow
Les articles publiés sur le site
-
No such filter in ffmpeg
10 mars, par sneha desaiI 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 HoopesI'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:
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 CarteretI'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_99I 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 MobileIn 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!