![](/img/trans.png)
[英]H264 video works using src attribute. Same video fails using the MediaSource API (Chromium)
[英]Javascript MediaSource API and H264 video
我在使用javascript MediaSource Extension API播放H264視頻時遇到問題。
我將在下面詳細介紹該方案。
我已經成功地實現了播放vp8,vp9,opus和vorbis編解碼器的音頻和視頻源的結果,也來自范圍請求(如果服務器具有使用任何字節范圍的功能)或chunked文件,使用shaka packager完成的塊。
當源是H264視頻時出現問題,在我的情況下,編解碼器是avc1.64001e和mp4a.40.2,完整的編解碼器字符串是視頻/ mp4;編解碼器=“avc1.64001e,mp4a.40.2”,但問題仍然存在與任何其他avc1編解碼器。
我想要做的是播放完整視頻的10兆字節塊,由字節范圍卷曲請求生成的塊使用-o在本地保存響應。
在shaka packager的流信息下面傳遞此文件作為輸入
[0530/161459:INFO:demuxer.cc(88)] Demuxer::Run() on file '10mega.mp4'.
[0530/161459:INFO:demuxer.cc(160)] Initialize Demuxer for file '10mega.mp4'.
File "10mega.mp4":
Found 2 stream(s).
Stream [0] type: Video
codec_string: avc1.64001e
time_scale: 17595
duration: 57805440 (3285.3 seconds)
is_encrypted: false
codec: H264
width: 720
height: 384
pixel_aspect_ratio: 1:1
trick_play_factor: 0
nalu_length_size: 4
Stream [1] type: Audio
codec_string: mp4a.40.2
time_scale: 44100
duration: 144883809 (3285.3 seconds)
is_encrypted: false
codec: AAC
sample_bits: 16
num_channels: 2
sampling_frequency: 44100
language: und
Packaging completed successfully.
該塊可以與外部媒體播放器應用程序(如VLC)一起播放,更重要的是, 使用<source>標簽將其添加到網頁時可以正常播放。
這是我在Chrome控制台中看到的錯誤
Uncaught (in promise) DOMException: Failed to load because no supported source was found.
下面是html和js代碼,如果你想重現(我使用內置的php7.2開發服務器進行了所有本地測試)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>VideoTest</title>
<link rel="icon" href="/favicon.ico" />
<script type="text/javascript" src="/script.js"></script>
<style>
video {
width: 98%;
height: 300px;
border: 0px solid #000;
display: flex;
}
</style>
</head>
<body>
<div id="videoContainer">
<video controls></video>
</div>
<video controls>
<source src="/media/10mega.mp4" type="video/mp4">
</video>
</body>
</html>
以下是JS代碼(scripjs)
class MediaTest {
constructor() {
}
init(link) {
this.link = link;
this.media = new MediaSource();
this.container = document.getElementsByTagName('video')[0];
this.container.src = window.URL.createObjectURL(this.media);
return new Promise(resolve => {
this.media.addEventListener('sourceopen', (e) => {
this.media = e.target;
return resolve(this);
});
});
}
addSourceBuffer() {
let codec = 'video/mp4;codecs="avc1.64001e, mp4a.40.2"';
let sourceBuffer = this.media.addSourceBuffer(codec);
// These are the same headers sent by the < source > tag
// with or without the issue remains
let headers = new Headers({
'Range': 'bytes=0-131072',
'Accept-Encoding': 'identity;q=1, *;q=0'
});
let requestData = {
headers: headers
};
let request = new Request(this.link, requestData);
return new Promise(resolve => {
fetch(request).then((response) => {
if(200 !== response.status) {
throw new Error('addSourceBuffer error with status ' + response.status);
}
return response.arrayBuffer();
}).then((buffer) => {
sourceBuffer.appendBuffer(buffer);
console.log('Buffer appended');
return resolve(this);
}).catch(function(e) {
console.log('addSourceBuffer error');
console.log(e);
});
});
}
play() {
this.container.play();
}
}
window.addEventListener('load', () => {
let media = new MediaTest();
media.init('/media/10mega.mp4').then(() => {
console.log('init ok');
return media.addSourceBuffer();
}).then((obj) => {
console.log('play');
media.play();
});
});
我想要實現的是使用MediaSource API播放文件,因為它使用<source>標簽很好地播放。 我不想對它進行解復用和重新編碼,而是按原樣使用它。
下面是從chrome:// media-internals中獲取的錯誤轉儲
render_id:180 player_id:11 pipeline_state:kStopped事件:WEBMEDIAPLAYER_DESTROYED
為了重現,我認為可以使用任何具有音頻和視頻軌道的H264視頻。
這個問題與我發現H264視頻使用src屬性的其他問題嚴格相關。 使用MediaSource API(Chromium)的同一視頻失敗,但它是從4年前開始的,所以我決定不回答那里。
有沒有人對這個問題有所了解? 有沒有辦法解決它或h264它與MSE不兼容?
提前致謝
它不是編解碼器,它是容器。 MSE需要碎片化的mp4文件。 不支持標准mp4。 對於標准mp4,您必須使用<video src="my.mp4">
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.