Recherche avancée

Médias (1)

Mot : - Tags -/biomaping

Autres articles (48)

  • Personnaliser les catégories

    21 juin 2013, par

    Formulaire de création d’une catégorie
    Pour ceux qui connaissent bien SPIP, une catégorie peut être assimilée à une rubrique.
    Dans le cas d’un document de type catégorie, les champs proposés par défaut sont : Texte
    On peut modifier ce formulaire dans la partie :
    Administration > Configuration des masques de formulaire.
    Dans le cas d’un document de type média, les champs non affichés par défaut sont : Descriptif rapide
    Par ailleurs, c’est dans cette partie configuration qu’on peut indiquer le (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

  • Contribute to translation

    13 avril 2011

    You can help us to improve the language used in the software interface to make MediaSPIP more accessible and user-friendly. You can also translate the interface into any language that allows it to spread to new linguistic communities.
    To do this, we use the translation interface of SPIP where the all the language modules of MediaSPIP are available. Just subscribe to the mailing list and request further informantion on translation.
    MediaSPIP is currently available in French and English (...)

Sur d’autres sites (10624)

  • ffmpeg Audiosegment error in get audio chunks in socketIo server in python

    26 janvier 2024, par a_crszkvc30Last_NameCol

    I want to send each audio chunk every minute.
this is the test code and i want to save audiofile and audio chunk file.
then, i will combine two audio files stop button was worked correctly but with set time function is not worked in python server.
there is python server code with socketio

    


    def handle_voice(sid,data): # blob 으로 들어온 데이터 
    # BytesIO를 사용하여 메모리 상에서 오디오 데이터를 로드
    audio_segment = AudioSegment.from_file(BytesIO(data), format="webm")
    directory = "dddd"
    # 오디오 파일로 저장
    #directory = str(names_sid.get(sid))
    if not os.path.exists(directory):
        os.makedirs(directory)
 
    # 오디오 파일로 저장
    file_path = os.path.join(directory, f'{sid}.wav')
    audio_segment.export(file_path, format='wav') 
    print('오디오 파일 저장 완료')`
 


    


    and there is client

    


    &#xA;&#xA;&#xA;&#xA;    &#xA;    &#xA;    <code class="echappe-js">&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.2/socket.io.js&quot;&gt;&lt;/script&gt;&#xA;&#xA;&#xA;&#xA;    &#xA;    
    

    &#xA;

    &#xA;

    &#xA; &lt;script&gt;&amp;#xA;        var socket = io(&amp;#x27;http://127.0.0.1:5000&amp;#x27;);&amp;#xA;        const record = document.getElementById(&quot;record&quot;)&amp;#xA;        const stop = document.getElementById(&quot;stop&quot;)&amp;#xA;        const soundClips = document.getElementById(&quot;sound-clips&quot;)&amp;#xA;        const chkHearMic = document.getElementById(&quot;chk-hear-mic&quot;)&amp;#xA;&amp;#xA;        const audioCtx = new(window.AudioContext || window.webkitAudioContext)() // 오디오 컨텍스트 정의&amp;#xA;&amp;#xA;        const analyser = audioCtx.createAnalyser()&amp;#xA;        //        const distortion = audioCtx.createWaveShaper()&amp;#xA;        //        const gainNode = audioCtx.createGain()&amp;#xA;        //        const biquadFilter = audioCtx.createBiquadFilter()&amp;#xA;&amp;#xA;        function makeSound(stream) {&amp;#xA;            const source = audioCtx.createMediaStreamSource(stream)&amp;#xA;            socket.connect()&amp;#xA;            source.connect(analyser)&amp;#xA;            //            analyser.connect(distortion)&amp;#xA;            //            distortion.connect(biquadFilter)&amp;#xA;            //            biquadFilter.connect(gainNode)&amp;#xA;            //            gainNode.connect(audioCtx.destination) // connecting the different audio graph nodes together&amp;#xA;            analyser.connect(audioCtx.destination)&amp;#xA;&amp;#xA;        }&amp;#xA;&amp;#xA;        if (navigator.mediaDevices) {&amp;#xA;            console.log(&amp;#x27;getUserMedia supported.&amp;#x27;)&amp;#xA;&amp;#xA;            const constraints = {&amp;#xA;                audio: true&amp;#xA;            }&amp;#xA;            let chunks = []&amp;#xA;&amp;#xA;            navigator.mediaDevices.getUserMedia(constraints)&amp;#xA;                .then(stream =&gt; {&amp;#xA;&amp;#xA;                    const mediaRecorder = new MediaRecorder(stream)&amp;#xA;                    &amp;#xA;                    chkHearMic.onchange = e =&gt; {&amp;#xA;                        if(e.target.checked == true) {&amp;#xA;                            audioCtx.resume()&amp;#xA;                            makeSound(stream)&amp;#xA;                        } else {&amp;#xA;                            audioCtx.suspend()&amp;#xA;                        }&amp;#xA;                    }&amp;#xA;                    &amp;#xA;                    record.onclick = () =&gt; {&amp;#xA;                        mediaRecorder.start(1000)&amp;#xA;                        console.log(mediaRecorder.state)&amp;#xA;                        console.log(&quot;recorder started&quot;)&amp;#xA;                        record.style.background = &quot;red&quot;&amp;#xA;                        record.style.color = &quot;black&quot;&amp;#xA;                    }&amp;#xA;&amp;#xA;                    stop.onclick = () =&gt; {&amp;#xA;                        mediaRecorder.stop()&amp;#xA;                        console.log(mediaRecorder.state)&amp;#xA;                        console.log(&quot;recorder stopped&quot;)&amp;#xA;                        record.style.background = &quot;&quot;&amp;#xA;                        record.style.color = &quot;&quot;&amp;#xA;                    }&amp;#xA;&amp;#xA;                    mediaRecorder.onstop = e =&gt; {&amp;#xA;                        console.log(&quot;data available after MediaRecorder.stop() called.&quot;)&amp;#xA;                        const bb = new Blob(chunks, { &amp;#x27;type&amp;#x27; : &amp;#x27;audio/wav&amp;#x27; })&amp;#xA;                        socket.emit(&amp;#x27;voice&amp;#x27;,bb)&amp;#xA;                        const clipName = prompt(&quot;오디오 파일 제목을 입력하세요.&quot;, new Date())&amp;#xA;&amp;#xA;                        const clipContainer = document.createElement(&amp;#x27;article&amp;#x27;)&amp;#xA;                        const clipLabel = document.createElement(&amp;#x27;p&amp;#x27;)&amp;#xA;                        const audio = document.createElement(&amp;#x27;audio&amp;#x27;)&amp;#xA;                        const deleteButton = document.createElement(&amp;#x27;button&amp;#x27;)&amp;#xA;&amp;#xA;                        clipContainer.classList.add(&amp;#x27;clip&amp;#x27;)&amp;#xA;                        audio.setAttribute(&amp;#x27;controls&amp;#x27;, &amp;#x27;&amp;#x27;)&amp;#xA;                        deleteButton.innerHTML = &quot;삭제&quot;&amp;#xA;                        clipLabel.innerHTML = clipName&amp;#xA;&amp;#xA;                        clipContainer.appendChild(audio)&amp;#xA;                        clipContainer.appendChild(clipLabel)&amp;#xA;                        clipContainer.appendChild(deleteButton)&amp;#xA;                        soundClips.appendChild(clipContainer)&amp;#xA;&amp;#xA;                        audio.controls = true&amp;#xA;                        const blob = new Blob(chunks, {&amp;#xA;                            &amp;#x27;type&amp;#x27;: &amp;#x27;audio/ogg codecs=opus&amp;#x27;&amp;#xA;                        })&amp;#xA;&amp;#xA;                        chunks = []&amp;#xA;                        const audioURL = URL.createObjectURL(blob)&amp;#xA;                        audio.src = audioURL&amp;#xA;                        console.log(&quot;recorder stopped&quot;)&amp;#xA;&amp;#xA;                        deleteButton.onclick = e =&gt; {&amp;#xA;                            evtTgt = e.target&amp;#xA;                            evtTgt  .parentNode.parentNode.removeChild(evtTgt.parentNode)&amp;#xA;                        }&amp;#xA;                    }&amp;#xA;&amp;#xA;                  mediaRecorder.ondataavailable = function(e) {&amp;#xA;                    chunks.push(e.data)&amp;#xA;                    if (chunks.length &gt;= 5)&amp;#xA;                    {&amp;#xA;                        const bloddb = new Blob(chunks, { &amp;#x27;type&amp;#x27; : &amp;#x27;audio/wav&amp;#x27; })&amp;#xA;                        socket.emit(&amp;#x27;voice&amp;#x27;, bloddb)&amp;#xA;                         &amp;#xA;                        chunks = []&amp;#xA;                    }&amp;#xA;                    mediaRecorder.sendData = function(buffer) {&amp;#xA;                        const bloddb = new Blob(buffer, { &amp;#x27;type&amp;#x27; : &amp;#x27;audio/wav&amp;#x27; })&amp;#xA;                        socket.emit(&amp;#x27;voice&amp;#x27;, bloddb)&amp;#xA;}&amp;#xA;};&amp;#xA;                })&amp;#xA;                .catch(err =&gt; {&amp;#xA;                    console.log(&amp;#x27;The following error occurred: &amp;#x27; &amp;#x2B; err)&amp;#xA;                })&amp;#xA;        }&amp;#xA;    &lt;/script&gt;&#xA;&#xA;

    &#xA;

    ask exception was never retrieved&#xA;future: <task finished="finished" coro="<InstrumentedAsyncServer._handle_event_internal()" defined="defined" at="at"> exception=CouldntDecodeError(&#x27;Decoding failed. ffmpeg returned error code: 3199971767\n\nOutput from ffmpeg/avlib:\n\nffmpeg version 6.1.1-full_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers\r\n  built with gcc 12.2.0 (Rev10, Built by MSYS2 project)\r\n  configuration: --enable-gpl --enable-version3 --enable-static --pkg-config=pkgconf --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-dxva2 --enable-d3d11va --enable-libvpl --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint\r\n  libavutil      58. 29.100 / 58. 29.100\r\n  libavcodec     60. 31.102 / 60. 31.102\r\n  libavformat    60. 16.100 / 60. 16.100\r\n  libavdevice    60.  3.100 / 60.  3.100\r\n  libavfilter     9. 12.100 /  9. 12.100\r\n  libswscale      7.  5.100 /  7.  5.100\r\n  libswresample   4. 12.100 /  4. 12.100\r\n  libpostproc    57.  3.100 / 57.  3.100\r\n[cache @ 000001d9828efe40] Inner protocol failed to seekback end : -40\r\n[matroska,webm @ 000001d9828efa00] EBML header parsing failed\r\n[cache @ 000001d9828efe40] Statistics, cache hits:0 cache misses:3\r\n[in#0 @ 000001d9828da3c0] Error opening input: Invalid data found when processing input\r\nError opening input file cache:pipe:0.\r\nError opening input files: Invalid data found when processing input\r\n&#x27;)>&#xA;Traceback (most recent call last):&#xA;  File "f:\fastapi-socketio-wb38\.vent\Lib\site-packages\socketio\async_admin.py", line 276, in _handle_event_internal&#xA;    ret = await self.sio.__handle_event_internal(server, sid, eio_sid,&#xA;          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&#xA;  File "f:\fastapi-socketio-wb38\.vent\Lib\site-packages\socketio\async_server.py", line 597, in _handle_event_internal&#xA;    r = await server._trigger_event(data[0], namespace, sid, *data[1:])&#xA;        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&#xA;  File "f:\fastapi-socketio-wb38\.vent\Lib\site-packages\socketio\async_server.py", line 635, in _trigger_event&#xA;    ret = handler(*args)&#xA;          ^^^^^^^^^^^^^^&#xA;  File "f:\fastapi-socketio-wb38\Python-Javascript-Websocket-Video-Streaming--main\poom2.py", line 153, in handle_voice&#xA;    audio_segment = AudioSegment.from_file(BytesIO(data), format="webm")&#xA;                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&#xA;  File "f:\fastapi-socketio-wb38\.vent\Lib\site-packages\pydub\audio_segment.py", line 773, in from_file&#xA;    raise CouldntDecodeError(&#xA;pydub.exceptions.CouldntDecodeError: Decoding failed. ffmpeg returned error code: 3199971767&#xA;&#xA;Output from ffmpeg/avlib:&#xA;&#xA;ffmpeg version 6.1.1-full_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers&#xA;  built with gcc 12.2.0 (Rev10, Built by MSYS2 project)&#xA;  configuration: --enable-gpl --enable-version3 --enable-static --pkg-config=pkgconf --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-dxva2 --enable-d3d11va --enable-libvpl --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint&#xA;  libavutil      58. 29.100 / 58. 29.100&#xA;  libavcodec     60. 31.102 / 60. 31.102&#xA;  libavformat    60. 16.100 / 60. 16.100&#xA;  libavdevice    60.  3.100 / 60.  3.100&#xA;  libavfilter     9. 12.100 /  9. 12.100&#xA;  libswscale      7.  5.100 /  7.  5.100&#xA;  libswresample   4. 12.100 /  4. 12.100&#xA;  libpostproc    57.  3.100 / 57.  3.100&#xA;[cache @ 000001d9828efe40] Inner protocol failed to seekback end : -40&#xA;[matroska,webm @ 000001d9828efa00] EBML header parsing failed&#xA;[cache @ 000001d9828efe40] Statistics, cache hits:0 cache misses:3&#xA;[in#0 @ 000001d9828da3c0] Error opening input: Invalid data found when processing input&#xA;Error opening input file cache:pipe:0.&#xA;Error opening input files: Invalid data found when processing input&#xA;</task>

    &#xA;

    im using version of ffmpeg-6.1.1-full_build.&#xA;i dont know this error exist the stop button sent event correctly. but chunk data was not work correctly in python server.&#xA;my english was so bad. sry

    &#xA;

  • 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).

    &#xA;

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

    &#xA;

    Any help would be much appreciated.

    &#xA;

    CDVDAUDIO.cpp

    &#xA;

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

    &#xA;

    CDVDAUdioCodecFFmpeg.cpp

    &#xA;

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

    &#xA;

    CDVDPlayerAudio.cpp

    &#xA;

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

    &#xA;

  • dockerized python application takes a long time to trim a video with ffmpeg

    15 avril 2024, par Ukpa Uchechi

    The project trims YouTube videos.

    &#xA;

    When I ran the ffmpeg command on the terminal, it didn't take too long to respond. The code below returns the trimmed video to the front end but it takes too long to respond. A 10 mins trim length takes about 5mins to respond. I am missing something, but I can't pinpoint the issue.

    &#xA;

    backend

    &#xA;

    main.py

    &#xA;

    import os&#xA;&#xA;from flask import Flask, request, send_file&#xA;from flask_cors import CORS, cross_origin&#xA;&#xA;&#xA;app = Flask(__name__)&#xA;cors = CORS(app)&#xA;&#xA;&#xA;current_directory = os.getcwd()&#xA;folder_name = "youtube_videos"&#xA;save_path = os.path.join(current_directory, folder_name)&#xA;output_file_path = os.path.join(save_path, &#x27;video.mp4&#x27;)&#xA;&#xA;os.makedirs(save_path, exist_ok=True)&#xA;&#xA;def convert_time_seconds(time_str):&#xA;    hours, minutes, seconds = map(int, time_str.split(&#x27;:&#x27;))&#xA;    total_seconds = (hours * 3600) &#x2B; (minutes * 60) &#x2B; seconds&#xA;&#xA;    return total_seconds&#xA;def convert_seconds_time(total_seconds):&#xA;    new_hours = total_seconds // 3600&#xA;    total_seconds %= 3600&#xA;    new_minutes = total_seconds // 60&#xA;    new_seconds = total_seconds % 60&#xA;&#xA;    new_time_str = f&#x27;{new_hours:02}:{new_minutes:02}:{new_seconds:02}&#x27;&#xA;&#xA;    return new_time_str&#xA;def add_seconds_to_time(time_str, seconds_to_add):&#xA;    total_seconds = convert_time_seconds(time_str)&#xA;&#xA;    total_seconds -= seconds_to_add&#xA;    new_time_str = convert_seconds_time(total_seconds)&#xA;&#xA;    return new_time_str&#xA;&#xA;def get_length(start_time, end_time):&#xA;    start_time_seconds = convert_time_seconds(start_time)&#xA;    end_time_seconds = convert_time_seconds(end_time)&#xA;&#xA;    length = end_time_seconds - start_time_seconds&#xA;&#xA;    length_str = convert_seconds_time(length)&#xA;    return length_str&#xA;    &#xA;def download_url(url):&#xA;    command = [&#xA;        "yt-dlp",&#xA;        "-g",&#xA;        url&#xA;    ]&#xA;    &#xA;    try:&#xA;        links = subprocess.run(command, capture_output=True, text=True, check=True)&#xA;        &#xA;        video, audio = links.stdout.strip().split("\n")&#xA;        &#xA;        return video, audio&#xA;&#xA;    except subprocess.CalledProcessError as e:&#xA;        print(f"Command failed with return code {e.returncode}.")&#xA;        print(f"Error output: {e.stderr}")&#xA;        return None&#xA;    except ValueError:&#xA;        print("Error: Could not parse video and audio links.")&#xA;        return None&#xA;    &#xA;&#xA;&#xA;def download_trimmed_video(video_link, audio_link, start_time, end_time):&#xA;    new_start_time = add_seconds_to_time(start_time, 30)&#xA;    new_end_time = get_length(start_time, end_time)&#xA;&#xA;    if os.path.exists(output_file_path):&#xA;        os.remove(output_file_path)&#xA;&#xA;&#xA;    command = [&#xA;        &#x27;ffmpeg&#x27;,&#xA;        &#x27;-ss&#x27;, new_start_time &#x2B; &#x27;.00&#x27;,&#xA;        &#x27;-i&#x27;, video_link,&#xA;        &#x27;-ss&#x27;, new_start_time &#x2B; &#x27;.00&#x27;,&#xA;        &#x27;-i&#x27;, audio_link,&#xA;        &#x27;-map&#x27;, &#x27;0:v&#x27;,&#xA;        &#x27;-map&#x27;, &#x27;1:a&#x27;,&#xA;        &#x27;-ss&#x27;, &#x27;30&#x27;,&#xA;        &#x27;-t&#x27;, new_end_time &#x2B; &#x27;.00&#x27;,&#xA;        &#x27;-c:v&#x27;, &#x27;libx264&#x27;,&#xA;        &#x27;-c:a&#x27;, &#x27;aac&#x27;,&#xA;        output_file_path&#xA;    ]&#xA;    try:&#xA;        result = subprocess.run(command, capture_output=True, text=True, check=True)&#xA;&#xA;        if result.returncode == 0:&#xA;            return "Trimmed video downloaded successfully!"&#xA;        else:&#xA;            return "Error occurred while downloading trimmed video"&#xA;    except subprocess.CalledProcessError as e:&#xA;        print(f"Command failed with return code {e.returncode}.")&#xA;        print(f"Error output: {e.stderr}")&#xA;&#xA;&#xA;app = Flask(__name__)&#xA;&#xA;&#xA;@app.route(&#x27;/trimvideo&#x27;, methods =["POST"])&#xA;@cross_origin()&#xA;def trim_video():&#xA;    print("here")&#xA;    data = request.get_json()&#xA;    video_link, audio_link = download_url(data["url"])&#xA;    if video_link and audio_link:&#xA;        print("Downloading trimmed video...")&#xA;        download_trimmed_video(video_link, audio_link, data["start_time"], data["end_time"])&#xA;        response = send_file(output_file_path, as_attachment=True, download_name=&#x27;video.mp4&#x27;)&#xA;    &#xA;        response.status_code = 200&#xA;&#xA;        return response&#xA;    else:&#xA;        return "Error downloading video", 400&#xA;&#xA;    &#xA;&#xA;&#xA;&#xA;&#xA;if __name__ == &#x27;__main__&#x27;:&#xA;    app.run(debug=True, port=5000, host=&#x27;0.0.0.0&#x27;)&#xA;

    &#xA;

    dockerfile

    &#xA;

    FROM ubuntu:latest&#xA;&#xA;# Update the package list and install wget and ffmpeg&#xA;RUN apt-get update \&#xA;    &amp;&amp; apt-get install -y wget ffmpeg python3 python3-pip \&#xA;    &amp;&amp; rm -rf /var/lib/apt/lists/*&#xA;&#xA;# Download the latest version of yt-dlp and install it&#xA;RUN wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp \&#xA;    &amp;&amp; chmod a&#x2B;rx /usr/local/bin/yt-dlp&#xA;&#xA;WORKDIR /app&#xA;&#xA;COPY main.py /app/&#xA;COPY requirements.txt /app/&#xA;&#xA;&#xA;RUN pip install --no-cache-dir -r requirements.txt&#xA;&#xA;&#xA;# Set the default command&#xA;CMD ["python3", "main.py"]&#xA;

    &#xA;

    requirements.txt

    &#xA;

    blinker==1.7.0&#xA;click==8.1.7&#xA;colorama==0.4.6&#xA;Flask==3.0.3&#xA;Flask-Cors==4.0.0&#xA;itsdangerous==2.1.2&#xA;Jinja2==3.1.3&#xA;MarkupSafe==2.1.5&#xA;Werkzeug==3.0.2&#xA;

    &#xA;

    frontend

    &#xA;

    App.js

    &#xA;

    &#xA;import React, { useState } from &#x27;react&#x27;;&#xA;import &#x27;./App.css&#x27;;&#xA;import axios from &#x27;axios&#x27;;&#xA;async function handleSubmit(event, url, start_time, end_time, setVideoUrl, setIsSubmitted){&#xA;  event.preventDefault();&#xA;&#xA;  if( url &amp;&amp; start_time &amp;&amp; end_time){&#xA;&#xA;    try {&#xA;      setIsSubmitted(true);&#xA;    const response = await axios.post(&#x27;http://127.0.0.1:5000/trimvideo&#x27;, {&#xA;      url: url,&#xA;      start_time: start_time,&#xA;      end_time: end_time&#xA;    },&#xA;    {&#xA;      responseType: &#x27;blob&#x27;,&#xA;      headers: {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;}&#xA;    }&#xA;  )&#xA;    const blob = new Blob([response.data], { type: &#x27;video/mp4&#x27; });&#xA;    const newurl = URL.createObjectURL(blob);&#xA;&#xA;&#xA;    setVideoUrl(newurl);&#xA;    } catch (error) {&#xA;      console.error(&#x27;Error trimming video:&#x27;, error);&#xA;    }&#xA;&#xA;  } else {&#xA;    alert(&#x27;Please fill all the fields&#x27;);&#xA;  }&#xA;}&#xA;&#xA;&#xA;function App() {&#xA;  const [url, setUrl] = useState(&#x27;&#x27;);&#xA;  const [startTime, setStartTime] = useState(&#x27;&#x27;);&#xA;  const [endTime, setEndTime] = useState(&#x27;&#x27;);&#xA;  const [videoUrl, setVideoUrl] = useState(&#x27;&#x27;);&#xA;  const [isSubmitted, setIsSubmitted] = useState(false);&#xA;  return (&#xA;    <div classname="App">&#xA;        <div classname="app-header">TRIM AND DOWNLOAD YOUR YOUTUBE VIDEO HERE</div>&#xA;        <input classname="input-url" placeholder="&#x27;Enter" value="{url}" />setUrl(e.target.value)}/>&#xA;        <div classname="input-container">&#xA;          <input classname="start-time-url" placeholder="start time" value="{startTime}" />setStartTime(e.target.value)}/>&#xA;          <input classname="end-time-url" placeholder="end time" value="{endTime}" />setEndTime(e.target.value)}/>&#xA;        &#xA;        </div>&#xA;        {&#xA;          !isSubmitted &amp;&amp; <button>> handleSubmit(event, url, startTime, endTime, setVideoUrl, setIsSubmitted)} className=&#x27;trim-button&#x27;>Trim</button>&#xA;        }&#xA;&#xA;        {&#xA;         ( isSubmitted &amp;&amp; !videoUrl) &amp;&amp;   <div classname="dot-pulse"></div>&#xA;        }&#xA;&#xA;&#xA;        {&#xA;          videoUrl &amp;&amp; <video controls="controls" autoplay="autoplay" width="500" height="360">&#xA;          <source src="{videoUrl}" type="&#x27;video/mp4&#x27;"></source>&#xA;        </video>&#xA;        }&#xA;&#xA;        &#xA;    </div>&#xA;  );&#xA;}&#xA;&#xA;export default App;&#xA;

    &#xA;