Здравствуйте!
Пытаюсь реализовать подгрузку видео через WebSocket. Само получение видео сделать удалось, но не получается теперь его воспроизвести.
По какой-то причине, когда я вызываю
mediaSource.endOfStream();
у тега video пропадает возможность запустить видео:
в то же время до этого вызова, есть возможность запустить его (само видео не работает, просто кнопки активны):
Ниже мой typescript код:
let mediaSource = new MediaSource();
let sourceBuffer: SourceBuffer;
let queue: Uint8Array[] = [];
let videoElement = document.querySelector('video') as HTMLVideoElement;
videoElement.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', function () {
console.log(mediaSource.sourceBuffers);
sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
console.log(sourceBuffer);
console.log(mediaSource.sourceBuffers);
sourceBuffer.addEventListener('updateend', function () {
// После добавления каждого фрагмента можно добавить следующие
if (queue.length > 0 && !sourceBuffer.updating) {
const buffer = queue.shift();
if (buffer !== undefined) {
sourceBuffer.appendBuffer(buffer);
}
}
});
});
// Функция для добавления фрагментов видео
function appendFragment(fragment: Uint8Array) {
queue.push(fragment);
if (sourceBuffer && !sourceBuffer.updating && queue.length > 0) {
const buffer = queue.shift();
if (buffer !== undefined) {
sourceBuffer.appendBuffer(buffer);
}
}
}
// Обработка окончания потока данных
function endStream() {
if (!sourceBuffer.updating) {
mediaSource.endOfStream();
} else {
// Подписка на событие updateend, чтобы вызвать endOfStream после завершения обновления
sourceBuffer.addEventListener('updateend', function onUpdateEnd() {
if (queue.length == 0) {
mediaSource.endOfStream();
videoElement.play();
// Удаляем обработчик, чтобы избежать повторного вызова
sourceBuffer.removeEventListener('updateend', onUpdateEnd);
}
});
}
}
interface VideoFragment {
fragment_time: number;
fragment_data: Uint8Array;
}
class Video {
video_uuid: string;
api: SocketHandler;
...
static async create(video_uuid:string){
const socket = new WebSocket('ws://' + window.location.host + '/ws/video/' + video_uuid);
const api = await SocketHandler.create(socket);
return new Video(video_uuid, api);
}
async start_load_video(){
let video = await this.api.get_info_about_video(this.video_uuid);
mediaSource.duration = video.video_duration;
for (let index = 0; index < Math.ceil(video.video_duration / video.splitted_time); index++) {
let fragment:VideoFragment = await this.api.get_video_fragment(index);
appendFragment(fragment.fragment_data);
}
endStream();
}
let video_uuid = window.location.pathname.split("/")[2];
Video.create(video_uuid).then(video => {
video.start_load_video();
});
Так у меня это реализовано.
Когда закрывается стрим, и вызывается
player.play()
, если предварительно потыкать по экрану, появляется данная ошибка:
Uncaught (in promise) DOMException: Failed to load because no supported source was found.