Recherche avancée

Médias (1)

Mot : - Tags -/wave

Autres articles (69)

  • 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

  • Support audio et vidéo HTML5

    10 avril 2011

    MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
    Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
    Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
    Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...)

  • De l’upload à la vidéo finale [version standalone]

    31 janvier 2010, par

    Le chemin d’un document audio ou vidéo dans SPIPMotion est divisé en trois étapes distinctes.
    Upload et récupération d’informations de la vidéo source
    Dans un premier temps, il est nécessaire de créer un article SPIP et de lui joindre le document vidéo "source".
    Au moment où ce document est joint à l’article, deux actions supplémentaires au comportement normal sont exécutées : La récupération des informations techniques des flux audio et video du fichier ; La génération d’une vignette : extraction d’une (...)

Sur d’autres sites (11142)

  • Crossdevice encoding static file to stream in browser using FFMPEG (segmented h264 ?)

    20 mars 2014, par Vprnl

    I'm building a mediacenter application in NodeJS which is going pretty ok.
    (you can check it out on Github : https://github.com/jansmolders86/mediacenterjs )

    I'm using FFMPEG to transcode local (static) movies to a stream which I then send to the browser.

    At first I used h264 with Flash which worked in browsers, but I really need it to work on Android an iOS (so no Flash) and preferably working on a Raspberry Pi.

    But getting it to play on all devices is driving me absolutely insane !

    I have all these bits of the puzzle I've gathered from countless hours reading articles, tutorials and stack overflow posts, which led me to the conclusion that I need to produce the following :

    • Use video codec H264 to transcode to MP4
    • Move the moovatom '-movflags' to make a MP4 streamable
    • Segment the stream so Apple can play the stream as well.

    But getting nowhere with this. Every time I produce a series of FFMPEG settings that either don't work, or work on some devices rather than all.

    Some of my failed attempt where :

    My flash attempt -> Main problem (not running in IOS) :

       '-y','-ss 0','-b 800k','-vcodec libx264','-acodec mp3'\
       '-ab 128','-ar 44100','-bufsize 62000', '-maxrate 620k'\
       metaDuration,tDuration,'-f flv

    my HLS attempt -> Main problem (not running in browser) :

           '-r 15','-b:v 128k','-c:v libx264','-x264opts level=41'\
           '-threads 4','-s 640x480','-map 0:v','-map 0:a:0','-c:a mp3'\
           '-b:a 160000','-ac 2','-f hls','-hls_time 10','-hls_list_size 6'\
           '-hls_wrap 18','-start_number 1'

    My MP4 attempt -> Main problem (duration is shortened and the later part of the video is speeding by)

          '-y','-ss 0','-b 800k','-vcodec libx264','-acodec mp3'\
          '-ab 128','-ar 44100','-bufsize 62000', '-maxrate 620k'\
          metaDuration,tDuration,'-f mp4','-movflags','frag_keyframe+empty_moov'

    Second MP4 attempt : -> Main problem (duration is shortened and the later part of the video is speeding by)

       '-y','-vcodec libx264','-pix_fmt yuv420p','-b 1200k','-flags +loop+mv4'\
       '-cmp 256','-partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8'\
       '-me_method hex','-subq 7','-trellis 1','-refs 5','-bf 3','-coder 1'\
       '-me_range 16','-g 150','-keyint_min 25','-sc_threshold 40'\
       '-i_qfactor 0.71','-acodec mp3','-qmin 10','-qdiff 4','-qmax 51'\
       '-ab 128k','-ar 44100','-threads 2','-f mp4','-movflags','frag_keyframe+empty_moov'])

    Here is an example of the FFMPEG log running with these settings :

           file conversion error ffmpeg version N-52458-gaa96439 Copyright (c) 2000-2013 the FFmpeg developers
             built on Apr 24 2013 22:19:32 with gcc 4.8.0 (GCC)
             configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --e
           nable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable
           -libgsm --enable-libilbc --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --ena
           ble-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwola
           me --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enabl
           e-libxvid --enable-zlib
             libavutil      52. 27.101 / 52. 27.101
             libavcodec     55.  6.100 / 55.  6.100
             libavformat    55.  3.100 / 55.  3.100
             libavdevice    55.  0.100 / 55.  0.100
             libavfilter     3. 60.101 /  3. 60.101
             libswscale      2.  2.100 /  2.  2.100
             libswresample   0. 17.102 /  0. 17.102
             libpostproc    52.  3.100 / 52.  3.100
           [avi @ 02427900] non-interleaved AVI
           Guessed Channel Layout for  Input Stream #0.1 : mono
           Input #0, avi, from 'C:/temp/the avengers.avi':
             Duration: 00:00:34.00, start: 0.000000, bitrate: 1433 kb/s
               Stream #0:0: Video: cinepak (cvid / 0x64697663), rgb24, 320x240, 15 tbr, 15 tbn, 15 tbc
               Stream #0:1: Audio: pcm_u8 ([1][0][0][0] / 0x0001), 22050 Hz, mono, u8, 176 kb/s
           Please use -b:a or -b:v, -b is ambiguous
           [libx264 @ 02527c60] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
           [libx264 @ 02527c60] profile High, level 2.0
           [libx264 @ 02527c60] 264 - core 130 r2274 c832fe9 - H.264/MPEG-4 AVC codec - Copyleft 2003-2013 - http://www.videolan.org/x26
           4.html - options: cabac=1 ref=5 deblock=1:0:0 analyse=0x3:0x133 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16
            chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=2 lookahead_threads=1 sliced_th
           reads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 we
           ightb=1 open_gop=0 weightp=2 keyint=150 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=abr mbtree=1 bitrate=120
           0 ratetol=1.0 qcomp=0.60 qpmin=10 qpmax=51 qpstep=4 ip_ratio=1.41 aq=1:1.00
           Output #0, mp4, to 'pipe:1':
             Metadata:
               encoder         : Lavf55.3.100
               Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 320x240, q=10-51, 1200 kb/s, 15360 tbn, 15 tbc
               Stream #0:1: Audio: mp3 (i[0][0][0] / 0x0069), 44100 Hz, mono, s16p, 128 kb/s
           Stream mapping:
             Stream #0:0 -> #0:0 (cinepak -> libx264)
             Stream #0:1 -> #0:1 (pcm_u8 -> libmp3lame)
           Press [q] to stop, [?] for help
           frame=  106 fps=0.0 q=10.0 size=       1kB time=00:00:06.94 bitrate=   1.4kbits/s
           frame=  150 fps=149 q=14.0 size=       1kB time=00:00:09.87 bitrate=   1.0kbits/s
           frame=  191 fps=126 q=16.0 size=       1kB time=00:00:12.61 bitrate=   0.8kbits/s
           frame=  244 fps=121 q=16.0 size=    2262kB time=00:00:16.14 bitrate=1147.6kbits/s
           frame=  303 fps=120 q=14.0 size=    2262kB time=00:00:20.08 bitrate= 922.2kbits/s
           frame=  354 fps=117 q=15.0 size=    3035kB time=00:00:23.48 bitrate=1058.6kbits/s
           frame=  402 fps=113 q=15.0 size=    3035kB time=00:00:26.67 bitrate= 932.1kbits/s
           frame=  459 fps=113 q=16.0 size=    4041kB time=00:00:30.43 bitrate=1087.7kbits/s
           frame=  510 fps=103 q=2686559.0 Lsize=    5755kB time=00:00:33.93 bitrate=1389.3kbits/s

           video:5211kB audio:531kB subtitle:0 global headers:0kB muxing overhead 0.235111%
           [libx264 @ 02527c60] frame I:6     Avg QP:10.55  size: 25921
           [libx264 @ 02527c60] frame P:245   Avg QP:12.15  size: 14543
           [libx264 @ 02527c60] frame B:259   Avg QP:15.55  size:  6242
           [libx264 @ 02527c60] consecutive B-frames:  6.1% 73.7% 14.7%  5.5%
           [libx264 @ 02527c60] mb I  I16..4: 19.9%  6.2% 73.9%
           [libx264 @ 02527c60] mb P  I16..4:  6.0%  0.2% 12.0%  P16..4: 35.4%  9.6% 16.3%  7.0%  5.6%    skip: 7.8%
           [libx264 @ 02527c60] mb B  I16..4:  0.7%  0.0%  4.3%  B16..8: 27.6% 17.2% 17.0%  direct:17.3%  skip:15.9%  L0:39.4% L1:43.2%
           BI:17.4%
           [libx264 @ 02527c60] final ratefactor: 11.41
           [libx264 @ 02527c60] 8x8 transform intra:1.6% inter:4.0%
           [libx264 @ 02527c60] coded y,uvDC,uvAC intra: 93.0% 97.0% 94.9% inter: 58.4% 58.7% 50.6%
           [libx264 @ 02527c60] i16 v,h,dc,p: 15% 26% 54%  5%
           [libx264 @ 02527c60] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16% 17% 39%  4%  4%  3%  1%  6%  9%
           [libx264 @ 02527c60] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 28% 34% 21%  4%  2%  2%  2%  2%  5%
           [libx264 @ 02527c60] i8c dc,h,v,p: 51% 24% 19%  6%
           [libx264 @ 02527c60] Weighted P-Frames: Y:4.1% UV:1.2%
           [libx264 @ 02527c60] ref P L0: 68.2%  9.8% 11.0%  5.6%  4.6%  0.8%  0.0%
           [libx264 @ 02527c60] ref B L0: 87.7%  8.0%  3.9%  0.4%
           [libx264 @ 02527c60] ref B L1: 97.8%  2.2%
           [libx264 @ 02527c60] kb/s:1255.36

    Lastly this is my node code fireing up FFMPEG. (I use the module Fluent-ffmpeg : https://github.com/schaermu/node-fluent-ffmpeg )

       var proc = new ffmpeg({ source: movie, nolog: true, timeout:15000})                        
           .addOptions(['-r 15','-b:v 128k','-c:v libx264','-x264opts level=41','-threads 4','-s 640x480','-map 0:v','-map 0:a:0','-c:a mp3','-b:a 160000','-ac 2','-f hls','-hls_time 10','-hls_list_size 6','-hls_wrap 18','-start_number 1 stream.m3u8'])
           .writeToStream(res, function(retcode, error){
               if (!error){
                   console.log('file has been converted succesfully',retcode .green);
               }else{
                   console.log('file conversion error',error .red);
               }
           });

    So to conclude this very long and code heavy question :

    I hope this does not come off as a lazy request, but could someone show/explain to me which FFMPEG settings could/should work on all platforms (modern browsers, Android and iOS) producing a stream of a static file which I can send to a HTML5 player.

    [EDIT] what I need if a generic option isn't available

    And if this is not possible as some posts might suggest, I would love to see a set of FFMPEG settings that get's the job done properly as far as mp4 streaming is concerned. (e.g encoding a streamable mp4).

    The streaming mp4 needs the following

    • A shifted moovAtom
    • It needs to be h264

    Thanks very much for your help !

  • Video streaming error : Uncaught (in promise) NotSupportedError : Failed to load because no supported source was found

    18 septembre 2024, par Aizen

    Here is my problem : I have one video src 1080p (on the frontend). On the frontend, I send this video-route to the backend :

    


    const req = async()=>{try{const res = await axios.get('/catalog/item',{params:{SeriesName:seriesName}});return {data:res.data};}catch(err){console.log(err);return false;}}const fetchedData = await req();-On the backend i return seriesName.Now i can make a full path,what the video is,and where it is,code:


    


    const videoUrl = 'C:/Users/arMori/Desktop/RedditClone/reddit/public/videos';console.log('IT VideoURL',videoUrl);


    


    const selectedFile = `${videoUrl}/${fetchedData.data.VideoSource}/${seriesName}-1080p.mp4`
console.log(`ITS'S SELECTED FILE: ${selectedFile}`);


    


    Ok, I have my src 1080p, now is the time to send it to the backend :

    


    const response = await axios.post('/videoFormat', {videoUrl:selectedFile})console.log('Это консоль лог путей: ',response.data);const videoPaths = response.data;


    


    Backend takes it and FFMpqg makes two types of resolution,720p and 480p,save it to the temp storage on backend, and then returns two routes where these videos stores

    


    async videoUpload(videoUrl:string){try{const tempDir = C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp;const inputFile = videoUrl;console.log('VIDEOURL: ',videoUrl);


    


            const outputFiles = [];&#xA;        &#xA;        await this.createDirectories(tempDir);        &#xA;        outputFiles.push(await this.convertVideo(inputFile, &#x27;1280x720&#x27;, &#x27;720p.mp4&#x27;));&#xA;        outputFiles.push(await this.convertVideo(inputFile, &#x27;854x480&#x27;, &#x27;480p.mp4&#x27;));&#xA;        console.log(&#x27;OUTUPT FILES SERVICE: &#x27;,outputFiles);&#xA;        &#xA;        return outputFiles;&#xA;&#xA;    }catch(err){&#xA;        console.error(&#x27;VideoFormatterService Error: &#x27;,err);&#xA;        &#xA;    }&#xA;}&#xA;&#xA;private convertVideo(inputPath:string,resolution:string,outputFileName:string):Promise<string>{&#xA;    const temp = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp`;&#xA;    return new Promise(async(resolve,reject)=>{&#xA;        const height = resolution.split(&#x27;x&#x27;)[1];&#xA;        console.log(&#x27;HIEGHT: &#x27;,height);&#xA;        &#xA;        const outputDir = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp/${height}p`;&#xA;        const outputPath = join(outputDir, outputFileName);&#xA;        const isExists = await fs.access(outputPath).then(() => true).catch(() => false);&#xA;        if(isExists){ &#xA;            console.log(`File already exists: ${outputPath}`);&#xA;            return resolve(outputPath)&#xA;        };&#xA;        ffmpeg(inputPath)&#xA;        .size(`${resolution}`)&#xA;        .videoCodec(&#x27;libx264&#x27;) // Кодек H.264&#xA;        .audioCodec(&#x27;aac&#x27;) &#xA;        .output(outputPath)&#xA;        .on(&#x27;end&#x27;,()=>resolve(outputPath))&#xA;        .on(&#x27;error&#x27;,(err)=>reject(err))&#xA;        .run()&#xA;            &#xA;    })&#xA;}&#xA;&#xA;private async createDirectories(temp:string){&#xA;    try{&#xA;        const dir720p = `${temp}/720p`;&#xA;        const dir480p = `${temp}/480p`;&#xA;        const dir720pExists = await fs.access(dir720p).then(() => true).catch(() => false);&#xA;        const dir480pExists = await fs.access(dir480p).then(() => true).catch(() => false);&#xA;        if(dir720pExists &amp;&amp; dir480pExists){&#xA;            console.log(&#x27;FILES ALIVE&#x27;);&#xA;            return;&#xA;        }&#xA;        if (!dir720pExists) {&#xA;            await fs.mkdir(dir720p, { recursive: true });&#xA;            console.log(&#x27;Папка 720p создана&#x27;);&#xA;        }&#xA;        &#xA;        if (!dir480pExists) {&#xA;            await fs.mkdir(dir480p, { recursive: true });&#xA;            console.log(&#x27;Папка 480p создана&#x27;);&#xA;        }&#xA;    } catch (err) {&#xA;        console.error(&#x27;Ошибка при создании директорий:&#x27;, err);&#xA;    }&#xA;}&#xA;</string>

    &#xA;

    Continue frontentd code :

    &#xA;

    let videoPath;&#xA;&#xA;if (quality === &#x27;720p&#x27;) {&#xA;        videoPath = videoPaths[0];&#xA;} else if (quality === &#x27;480p&#x27;) {&#xA;        videoPath = videoPaths[1];&#xA;}&#xA;&#xA;if (!videoPath) {&#xA;        console.error(&#x27;Video path not found!&#x27;);&#xA;        return;&#xA;}&#xA;&#xA;// Получаем видео по его пути&#xA;console.log(&#x27;VIDEOPATH LOG: &#x27;,videoPath);&#xA;    &#xA;const videoRes = await axios.get(&#x27;/videoFormat/getVideo&#x27;, { &#xA;        params: { path: videoPath } ,&#xA;        headers: { Range: &#x27;bytes=0-&#x27; },&#xA;        responseType: &#x27;blob&#x27;&#xA;    });&#xA;    console.log(&#x27;Video fetched: &#x27;, videoRes);&#xA;    const videoBlob = new Blob([videoRes.data], { type: &#x27;video/mp4&#x27; });&#xA;    const videoURL = URL.createObjectURL(videoBlob);&#xA;    return videoURL;&#xA;    /* console.log(&#x27;Видео успешно загружено:&#x27;, response.data); */&#xA;    } catch (error) {&#xA;    console.error(&#x27;Ошибка при загрузке видео:&#x27;, error);&#xA;    }&#xA;}&#xA;

    &#xA;

    Here I just choose one of the route and make a new GET request (VideoRes), now in the controller in the backend, I'm trying to do a video streaming :

    &#xA;

    @Public()&#xA;    @Get(&#x27;/getVideo&#x27;)&#xA;    async getVideo(@Query(&#x27;path&#x27;) videoPath:string,@Req() req:Request,@Res() res:Response){&#xA;        try {&#xA;            console.log(&#x27;PATH ARGUMENT: &#x27;,videoPath);&#xA;            console.log(&#x27;VIDEOPATH IN SERVICE: &#x27;,videoPath);&#xA;        const videoSize = (await fs.stat(videoPath)).size;&#xA;        const CHUNK_SIZE = 10 ** 6;&#xA;        const range = req.headers[&#x27;range&#x27;] as string | undefined;&#xA;        if (!range) {&#xA;            return new ForbiddenException(&#x27;Range не найденно&#x27;);&#xA;        }&#xA;        const start = Number(range.replace(/\D/g,""));&#xA;        const end = Math.min(start &#x2B; CHUNK_SIZE,videoSize - 1);&#xA;&#xA;        const contentLength = end - start &#x2B; 1;&#xA;        const videoStream = fsSync.createReadStream(videoPath, { start, end });&#xA;        const headers = {&#xA;            &#x27;Content-Range&#x27;:`bytes ${start}-${end}/${videoSize}`,&#xA;            &#x27;Accept-Ranges&#x27;:&#x27;bytes&#x27;,&#xA;            &#x27;Content-Length&#x27;:contentLength,&#xA;            &#x27;Content-Type&#x27;:&#x27;video/mp4&#x27;&#xA;        }&#xA;        &#xA;        res.writeHead(206,headers);&#xA;&#xA;        // Передаем поток в ответ&#xA;        videoStream.pipe(res);&#xA;        &#xA;&#xA;        // Если возникнет ошибка при стриминге, логируем ошибку&#xA;        videoStream.on(&#x27;error&#x27;, (error) => {&#xA;            console.error(&#x27;Ошибка при чтении видео:&#x27;, error);&#xA;            res.status(500).send(&#x27;Ошибка при чтении видео&#x27;);&#xA;        });&#xA;        } catch (error) {&#xA;            console.error(&#x27;Ошибка при обработке запросов:&#x27;, error);&#xA;            return res.status(400).json({ message: &#x27;Ошибка при обработке getVideo запросов&#x27; });&#xA;        }&#xA;    }&#xA;

    &#xA;

    Send to the frontend

    &#xA;

    res.writeHead(206,headers);&#xA;

    &#xA;

    In the frontend, I make blob url for video src and return it

    &#xA;

    const videoBlob = new Blob([videoRes.data], { type: &#x27;video/mp4&#x27; });const videoURL = URL.createObjectURL(videoBlob);return videoURL;&#xA;

    &#xA;

    And assign src to the video :

    &#xA;

    useVideo(seriesName,quality).then(src => {&#xA;                if (src) {&#xA;                    console.log(&#x27;ITS VIDEOLOGISC GOIDA!&#x27;);&#xA;                    if(!playRef.current) return;&#xA;                    &#xA;                    const oldURL = playRef.current.src;&#xA;                    if (oldURL &amp;&amp; oldURL.startsWith(&#x27;blob:&#x27;)) {&#xA;                        URL.revokeObjectURL(oldURL);&#xA;                    }&#xA;                    playRef.current.pause();&#xA;                    playRef.current.src = &#x27;&#x27;;&#xA;                    setQuality(quality);&#xA;                    console.log(&#x27;SRC: &#x27;,src);&#xA;                    &#xA;                    playRef.current.src = src;&#xA;                    playRef.current.load();&#xA;                    console.log(&#x27;ITS VIDEOURL GOIDA!&#x27;);&#xA;                    togglePlayPause();&#xA;                }&#xA;            })&#xA;            .catch(err => console.error(&#x27;Failed to fetch video&#x27;, err));&#xA;

    &#xA;

    But the problem is :

    &#xA;

    &#xA;

    Vinland-Saga:1 Uncaught (in promise) NotSupportedError : Failed to load because no supported source was found

    &#xA;

    &#xA;

    And I don't know why...

    &#xA;

    I tried everything, but I don't understand why src is incorrect..

    &#xA;

  • Video streamign with FFMpeg and Nest.js+Next.js

    17 septembre 2024, par Aizen

    Here is my problem : I have one video src 1080p (on the frontend). On the frontend, I send this video-route to the backend :

    &#xA;

    const req = async()=>{try{const res = await axios.get(&#x27;/catalog/item&#x27;,{params:{SeriesName:seriesName}});return {data:res.data};}catch(err){console.log(err);return false;}}const fetchedData = await req();-On the backend i return seriesName.Now i can make a full path,what the video is,and where it is,code:&#xA;

    &#xA;

    const videoUrl = &#x27;C:/Users/arMori/Desktop/RedditClone/reddit/public/videos&#x27;;console.log(&#x27;IT VideoURL&#x27;,videoUrl);&#xA;

    &#xA;

    const selectedFile = `${videoUrl}/${fetchedData.data.VideoSource}/${seriesName}-1080p.mp4`&#xA;console.log(`ITS&#x27;S SELECTED FILE: ${selectedFile}`);&#xA;

    &#xA;

    Ok, I have my src 1080p, now is the time to send it to the backend :

    &#xA;

    const response = await axios.post(&#x27;/videoFormat&#x27;, {videoUrl:selectedFile})console.log(&#x27;Это консоль лог путей: &#x27;,response.data);const videoPaths = response.data;&#xA;

    &#xA;

    Backend takes it and FFMpqg makes two types of resolution,720p and 480p,save it to the temp storage on backend, and then returns two routes where these videos stores

    &#xA;

    async videoUpload(videoUrl:string){try{const tempDir = C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp;const inputFile = videoUrl;console.log(&#x27;VIDEOURL: &#x27;,videoUrl);&#xA;

    &#xA;

            const outputFiles = [];&#xA;        &#xA;        await this.createDirectories(tempDir);        &#xA;        outputFiles.push(await this.convertVideo(inputFile, &#x27;1280x720&#x27;, &#x27;720p.mp4&#x27;));&#xA;        outputFiles.push(await this.convertVideo(inputFile, &#x27;854x480&#x27;, &#x27;480p.mp4&#x27;));&#xA;        console.log(&#x27;OUTUPT FILES SERVICE: &#x27;,outputFiles);&#xA;        &#xA;        return outputFiles;&#xA;&#xA;    }catch(err){&#xA;        console.error(&#x27;VideoFormatterService Error: &#x27;,err);&#xA;        &#xA;    }&#xA;}&#xA;&#xA;private convertVideo(inputPath:string,resolution:string,outputFileName:string):Promise<string>{&#xA;    const temp = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp`;&#xA;    return new Promise(async(resolve,reject)=>{&#xA;        const height = resolution.split(&#x27;x&#x27;)[1];&#xA;        console.log(&#x27;HIEGHT: &#x27;,height);&#xA;        &#xA;        const outputDir = `C:/Users/arMori/Desktop/RedditClone/reddit_back/src/video/temp/${height}p`;&#xA;        const outputPath = join(outputDir, outputFileName);&#xA;        const isExists = await fs.access(outputPath).then(() => true).catch(() => false);&#xA;        if(isExists){ &#xA;            console.log(`File already exists: ${outputPath}`);&#xA;            return resolve(outputPath)&#xA;        };&#xA;        ffmpeg(inputPath)&#xA;        .size(`${resolution}`)&#xA;        .videoCodec(&#x27;libx264&#x27;) // Кодек H.264&#xA;        .audioCodec(&#x27;aac&#x27;) &#xA;        .output(outputPath)&#xA;        .on(&#x27;end&#x27;,()=>resolve(outputPath))&#xA;        .on(&#x27;error&#x27;,(err)=>reject(err))&#xA;        .run()&#xA;            &#xA;    })&#xA;}&#xA;&#xA;private async createDirectories(temp:string){&#xA;    try{&#xA;        const dir720p = `${temp}/720p`;&#xA;        const dir480p = `${temp}/480p`;&#xA;        const dir720pExists = await fs.access(dir720p).then(() => true).catch(() => false);&#xA;        const dir480pExists = await fs.access(dir480p).then(() => true).catch(() => false);&#xA;        if(dir720pExists &amp;&amp; dir480pExists){&#xA;            console.log(&#x27;FILES ALIVE&#x27;);&#xA;            return;&#xA;        }&#xA;        if (!dir720pExists) {&#xA;            await fs.mkdir(dir720p, { recursive: true });&#xA;            console.log(&#x27;Папка 720p создана&#x27;);&#xA;        }&#xA;        &#xA;        if (!dir480pExists) {&#xA;            await fs.mkdir(dir480p, { recursive: true });&#xA;            console.log(&#x27;Папка 480p создана&#x27;);&#xA;        }&#xA;    } catch (err) {&#xA;        console.error(&#x27;Ошибка при создании директорий:&#x27;, err);&#xA;    }&#xA;}&#xA;</string>

    &#xA;

    Continue frontentd code :

    &#xA;

    let videoPath;&#xA;&#xA;if (quality === &#x27;720p&#x27;) {&#xA;        videoPath = videoPaths[0];&#xA;} else if (quality === &#x27;480p&#x27;) {&#xA;        videoPath = videoPaths[1];&#xA;}&#xA;&#xA;if (!videoPath) {&#xA;        console.error(&#x27;Video path not found!&#x27;);&#xA;        return;&#xA;}&#xA;&#xA;// Получаем видео по его пути&#xA;console.log(&#x27;VIDEOPATH LOG: &#x27;,videoPath);&#xA;    &#xA;const videoRes = await axios.get(&#x27;/videoFormat/getVideo&#x27;, { &#xA;        params: { path: videoPath } ,&#xA;        headers: { Range: &#x27;bytes=0-&#x27; },&#xA;        responseType: &#x27;blob&#x27;&#xA;    });&#xA;    console.log(&#x27;Video fetched: &#x27;, videoRes);&#xA;    const videoBlob = new Blob([videoRes.data], { type: &#x27;video/mp4&#x27; });&#xA;    const videoURL = URL.createObjectURL(videoBlob);&#xA;    return videoURL;&#xA;    /* console.log(&#x27;Видео успешно загружено:&#x27;, response.data); */&#xA;    } catch (error) {&#xA;    console.error(&#x27;Ошибка при загрузке видео:&#x27;, error);&#xA;    }&#xA;}&#xA;

    &#xA;

    Here I just choose one of the route and make a new GET request (VideoRes), now in the controller in the backend, I'm trying to do a video streaming :

    &#xA;

    @Public()&#xA;    @Get(&#x27;/getVideo&#x27;)&#xA;    async getVideo(@Query(&#x27;path&#x27;) videoPath:string,@Req() req:Request,@Res() res:Response){&#xA;        try {&#xA;            console.log(&#x27;PATH ARGUMENT: &#x27;,videoPath);&#xA;            console.log(&#x27;VIDEOPATH IN SERVICE: &#x27;,videoPath);&#xA;        const videoSize = (await fs.stat(videoPath)).size;&#xA;        const CHUNK_SIZE = 10 ** 6;&#xA;        const range = req.headers[&#x27;range&#x27;] as string | undefined;&#xA;        if (!range) {&#xA;            return new ForbiddenException(&#x27;Range не найденно&#x27;);&#xA;        }&#xA;        const start = Number(range.replace(/\D/g,""));&#xA;        const end = Math.min(start &#x2B; CHUNK_SIZE,videoSize - 1);&#xA;&#xA;        const contentLength = end - start &#x2B; 1;&#xA;        const videoStream = fsSync.createReadStream(videoPath, { start, end });&#xA;        const headers = {&#xA;            &#x27;Content-Range&#x27;:`bytes ${start}-${end}/${videoSize}`,&#xA;            &#x27;Accept-Ranges&#x27;:&#x27;bytes&#x27;,&#xA;            &#x27;Content-Length&#x27;:contentLength,&#xA;            &#x27;Content-Type&#x27;:&#x27;video/mp4&#x27;&#xA;        }&#xA;        &#xA;        res.writeHead(206,headers);&#xA;&#xA;        // Передаем поток в ответ&#xA;        videoStream.pipe(res);&#xA;        &#xA;&#xA;        // Если возникнет ошибка при стриминге, логируем ошибку&#xA;        videoStream.on(&#x27;error&#x27;, (error) => {&#xA;            console.error(&#x27;Ошибка при чтении видео:&#x27;, error);&#xA;            res.status(500).send(&#x27;Ошибка при чтении видео&#x27;);&#xA;        });&#xA;        } catch (error) {&#xA;            console.error(&#x27;Ошибка при обработке запросов:&#x27;, error);&#xA;            return res.status(400).json({ message: &#x27;Ошибка при обработке getVideo запросов&#x27; });&#xA;        }&#xA;    }&#xA;

    &#xA;

    Send to the frontend

    &#xA;

    res.writeHead(206,headers);&#xA;

    &#xA;

    In the frontend, I make blob url for video src and return it

    &#xA;

    const videoBlob = new Blob([videoRes.data], { type: &#x27;video/mp4&#x27; });const videoURL = URL.createObjectURL(videoBlob);return videoURL;&#xA;

    &#xA;

    And assign src to the video :

    &#xA;

    useVideo(seriesName,quality).then(src => {&#xA;                if (src) {&#xA;                    console.log(&#x27;ITS VIDEOLOGISC GOIDA!&#x27;);&#xA;                    if(!playRef.current) return;&#xA;                    &#xA;                    const oldURL = playRef.current.src;&#xA;                    if (oldURL &amp;&amp; oldURL.startsWith(&#x27;blob:&#x27;)) {&#xA;                        URL.revokeObjectURL(oldURL);&#xA;                    }&#xA;                    playRef.current.pause();&#xA;                    playRef.current.src = &#x27;&#x27;;&#xA;                    setQuality(quality);&#xA;                    console.log(&#x27;SRC: &#x27;,src);&#xA;                    &#xA;                    playRef.current.src = src;&#xA;                    playRef.current.load();&#xA;                    console.log(&#x27;ITS VIDEOURL GOIDA!&#x27;);&#xA;                    togglePlayPause();&#xA;                }&#xA;            })&#xA;            .catch(err => console.error(&#x27;Failed to fetch video&#x27;, err));&#xA;

    &#xA;

    But the problem is :

    &#xA;

    &#xA;

    Vinland-Saga:1 Uncaught (in promise) NotSupportedError : Failed to load because no supported source was found

    &#xA;

    &#xA;

    And I don't know why...

    &#xA;

    I tried everything, but I don't understand why src is incorrect..

    &#xA;