Mediasource Api
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.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: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.
■ 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
A teszt környezet: OS: Win10, Browser: Chrome 98.0.4758.102, Ffmpeg: version 2022-02-24-git-8ef03c2ff1-full
A forrásom:
<video muted controls></video>
<script>
segments = [];
last_segment = 0;
mimeCodec = 'video/mp4; codecs="avc1.64000d,mp4a.40.2"';
timestampOffset = 0;
video = document.querySelector('video');
mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
sourceBuffer = null;
segment_process = false;
mediaSource.addEventListener('sourceopen', function(){
sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
sourceBuffer.mode = 'segments';
// Initialization
const init_xhr = new XMLHttpRequest();
init_xhr.open('get', 'init.mp4');
init_xhr.setRequestHeader('Cache-Control', 'no-cache');
init_xhr.responseType = 'arraybuffer';
init_xhr.send();
init_xhr.onload = function(){
sourceBuffer.appendBuffer(init_xhr.response);
sourceBuffer.addEventListener('updateend', event = function(){
sourceBuffer.removeEventListener('updateend', event);
sourceBuffer.timestampOffset = 0;
sourceBuffer.remove(0,1);
manifestInitialization(function(){
if (segments.length > 0 && segment_process == false){
segments = segments.slice(-1);
segmentProccess();
}
});
});
};
}.bind(mediaSource));
setInterval(function(){
manifestInitialization(function(){
if (segments.length > 0 && segment_process == false){
segmentProccess();
}
});
},500);
// Manifest Initialization
function manifestInitialization(callback){
const manifest_xhr = new XMLHttpRequest();
manifest_xhr.open('get', 'ehls/manifest');
manifest_xhr.setRequestHeader('Cache-Control', 'no-cache');
manifest_xhr.responseType = 'text';
manifest_xhr.send();
manifest_xhr.onload = function(e){
lines = manifest_xhr.responseText.split(/\r?\n/);
lines.forEach(function(line){
line = line.split(';');
const segment = {id: Number(line[0]), file: line[1], duration: Number(line[2]), type: Number(line[3])};
if (!objectInArray(segment, segments) && segment.id > last_segment){
segments.push(segment);
last_segment = segment.id;
}
});
callback();
};
};
// Segment Load
function segmentProccess(){
segment_process = true;
segment = segments.shift();
const segment_xhr = new XMLHttpRequest();
segment_xhr.open('get', 'ehls/' + segment.file);
segment_xhr.setRequestHeader('Cache-Control', 'no-cache');
segment_xhr.responseType = 'arraybuffer';
segment_xhr.send();
segment_xhr.onload = function(){
timestampOffset += segment.duration;
sourceBuffer.appendBuffer(segment_xhr.response);
sourceBuffer.addEventListener('updateend', event = function(){
sourceBuffer.removeEventListener('updateend', event);
sourceBuffer.timestampOffset = timestampOffset;
video.oncanplay = function(){
video.play();
};
if (segments.length > 0){
segmentProccess();
}
else{
segment_process = false;
}
});
};
};
// Object in array
function objectInArray(sObj, array){
returnV = false;
array.forEach(function(aObj){
if (JSON.stringify(sObj) == JSON.stringify(aObj)){
returnV = true;
}
});
return returnV;
};
</script>
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.