ugrás a tartalomhoz

Mediasource Api

alkony4 · 2022. Már. 23. (Sze), 17.58
Szervusztok!

A kérdés kissé összetett és sajnos nem nagyon tudom melyik topik felelne meg a kérdés feltételének (ha netán rossz a hely előre is sorry).

Szeretnék egy saját mediastreamet, saját stream player kialakításával megvalósítani.
Alapul az ffmpeg szegmentálási lehetőségét vettem amit azonos hosszúságú videókra oszt egy meglévő videót realtime.
ffmpeg -re -i input.mkv -map 0:v:0 -map 0:a:0 -c:v libx264 -pix_fmt yuv420p -vf scale=1280:720 -c:a copy -sample_rate 44100 -segment_time 2 -r 30 -g 1 -sc_threshold 0 -force_key_frames ""expr:gte(t,n_forced*1)"" -flags +cgop+low_delay -f segment -segment_format_options movflags=+empty_moov+omit_tfhd_offset+frag_keyframe+default_base_moof+isml -segment_list_type ext -segment_list {segment_file_dir} output_%d.mp4
Ezzel szépen létre is jönnek a szeletek amit aztán megetetek a mediasource extesnion apival. A módszer 'működik' is... azzal a hibával hogy, a képi és hangi anyag egy idő után elcsúszik egymástól. Ez csak chrome böngészőben következett eddig be, firefoxban nem.

A teszt környezet: OS: Win10, Browser: Chrome 98.0.4758.102, Ffmpeg: version 2022-02-24-git-8ef03c2ff1-full

A forrásom:
  1. <video muted controls></video>  
  2.   
  3. <script>  
  4.     segments = [];  
  5.     last_segment = 0;  
  6.     mimeCodec = 'video/mp4; codecs="avc1.64000d,mp4a.40.2"';  
  7.     timestampOffset = 0;  
  8.     video = document.querySelector('video');  
  9.     mediaSource = new MediaSource();  
  10.     video.src = URL.createObjectURL(mediaSource);  
  11.     sourceBuffer = null;  
  12.     segment_process = false;  
  13.       
  14.       
  15.     mediaSource.addEventListener('sourceopen', function(){  
  16.         sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);  
  17.         sourceBuffer.mode = 'segments';  
  18.           
  19.         // Initialization  
  20.         const init_xhr = new XMLHttpRequest();  
  21.         init_xhr.open('get', 'init.mp4');  
  22.         init_xhr.setRequestHeader('Cache-Control', 'no-cache');  
  23.         init_xhr.responseType = 'arraybuffer';  
  24.         init_xhr.send();  
  25.         init_xhr.onload = function(){  
  26.             sourceBuffer.appendBuffer(init_xhr.response);  
  27.             sourceBuffer.addEventListener('updateend', event = function(){  
  28.                 sourceBuffer.removeEventListener('updateend', event);  
  29.                 sourceBuffer.timestampOffset = 0;  
  30.                 sourceBuffer.remove(0,1);  
  31.                   
  32.                 manifestInitialization(function(){  
  33.                     if (segments.length > 0 && segment_process == false){  
  34.                         segmentssegments = segments.slice(-1);  
  35.                         segmentProccess();  
  36.                     }  
  37.                 });  
  38.             });  
  39.         };  
  40.     }.bind(mediaSource));  
  41.       
  42.       
  43.     setInterval(function(){  
  44.         manifestInitialization(function(){  
  45.             if (segments.length > 0 && segment_process == false){  
  46.                 segmentProccess();  
  47.             }  
  48.         });  
  49.     },500);  
  50.       
  51.       
  52.     // Manifest Initialization  
  53.     function manifestInitialization(callback){  
  54.         const manifest_xhr = new XMLHttpRequest();  
  55.           
  56.         manifest_xhr.open('get', 'ehls/manifest');  
  57.         manifest_xhr.setRequestHeader('Cache-Control', 'no-cache');  
  58.         manifest_xhr.responseType = 'text';  
  59.         manifest_xhr.send();  
  60.           
  61.         manifest_xhr.onload = function(e){  
  62.             lines = manifest_xhr.responseText.split(/\r?\n/);  
  63.             lines.forEach(function(line){  
  64.                 lineline = line.split(';');  
  65.                 const segment = {id: Number(line[0]), file: line[1], duration: Number(line[2]), type: Number(line[3])};  
  66.                 if (!objectInArray(segment, segments) && segment.id > last_segment){  
  67.                     segments.push(segment);  
  68.                     last_segment = segment.id;  
  69.                 }  
  70.             });  
  71.             callback();  
  72.         };  
  73.     };  
  74.       
  75.       
  76.     // Segment Load  
  77.     function segmentProccess(){  
  78.         segment_process = true;  
  79.         segment = segments.shift();  
  80.         const segment_xhr = new XMLHttpRequest();  
  81.         segment_xhr.open('get', 'ehls/' + segment.file);  
  82.         segment_xhr.setRequestHeader('Cache-Control', 'no-cache');  
  83.         segment_xhr.responseType = 'arraybuffer';  
  84.         segment_xhr.send();  
  85.         segment_xhr.onload = function(){  
  86.             timestampOffset += segment.duration;  
  87.             sourceBuffer.appendBuffer(segment_xhr.response);  
  88.             sourceBuffer.addEventListener('updateend', event = function(){  
  89.                 sourceBuffer.removeEventListener('updateend', event);  
  90.                     sourceBuffer.timestampOffset = timestampOffset;  
  91.                     video.oncanplay = function(){  
  92.                         video.play();  
  93.                     };  
  94.                     if (segments.length > 0){  
  95.                         segmentProccess();  
  96.                         }  
  97.                     else{  
  98.                         segment_process = false;  
  99.                         }  
  100.             });  
  101.         };  
  102.     };  
  103.       
  104.       
  105.     // Object in array  
  106.     function objectInArray(sObj, array){  
  107.         returnV = false;  
  108.         array.forEach(function(aObj){  
  109.             if (JSON.stringify(sObj) == JSON.stringify(aObj)){  
  110.                 returnV = true;  
  111.             }  
  112.         });  
  113.         return returnV;  
  114.     };  
  115.       
  116. </script>  
Illetve chrome által az alábbi hibaüzenetekre lettem figyelmes: logpic

Akadt e bárkinek ehhez hasonló problémája? Mit rontok el és miként javítható ez szerintetek?

Megtisztelő válaszotok előre is köszönöm.