我在使用javascript MediaSource扩展API播放H264视频时遇到问题。
我将在下面详细描述这个场景。
我已经成功地实现了播放vp8、vp9、opus和vobis编解码器的音频和视频源的结果,也来自范围请求(如果服务器有能力,使用任何字节范围)或分块文件,使用shaka打包器完成的块。
当源是H264视频时,问题就来了,在我的例子中,详细的编解码器是avc1.64001e和mp4A.40.2,完整的编解码器字符串是video/mp4;codecs="avc1.64001e, mp4A.40.2"但任何其他avc1编解码器仍然会出现问题。
我想做的是播放完整视频的一个10兆字节的块,这个块是由byterange curl请求生成的,使用-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)一起播放,更重要的是,它可以使用
这就是我在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播放文件,因为它使用
下面是从chrome://media-internals
渲染id:180播放器id:11管道状态:kStopped事件:WEBMEDIAPLAYER被销毁
为了重现,我认为可以使用任何包含音频和视频轨迹的H264视频。
这个问题与我发现的使用src属性的H264视频作品的另一个问题密切相关。同样的视频在使用MediaSource API(Chromium)时失败,但这是4年前的视频,所以我决定不回答这个问题。
有人知道这个问题吗?有什么方法可以解决它吗?h264它只是与MSE不兼容?
提前谢谢
它不是编解码器,它是容器。MSE需要碎片mp4文件。不支持标准mp4。对于标准mp4,您必须使用
应用程序创建的h264帧被发送到标准输出,在标准输出中,使用ffmpeg将该流重新复用为mp4,并将其传递给服务器,服务器根据请求将其传递给客户端。 这是个好办法吗?这甚至可能创建一个低延迟30fps视频流使用这种方法?
我现在正在Android上对一个h264字节流进行解码。流是从第三方产品发送的,我不太确定它的视频格式。该文件说,流由PPS和SPS NAL单位组成。但我接收到的h264字节流包括以0x00、0x00、0x00、0x01开头的序列,并且在我接收到的样本中,第5个字节可能是0x09、0x21或0x06。这让我兴奋了一段时间,因为它似乎与通常的0x67或0x68指示器不同。有人知道NAL单元头中的0x
我可以看到视频播放在我的TextureView,但它是相当腐败。我已经验证了我正在以正确的顺序接收完整的数据包。我已经能够正确解析RTP头。我相信我的问题与SPS和PPS以及MediaCodec有关。 正如您所看到的,我没有从我的视频流中为MediaFormat提供SPS和PPS,而是使用了一个internet示例中的硬编码集。我试图找到解释如何从数据包中提取SPS和PPS的源,但没有找到任何东西
我正在开发一个通过RTP接收H264编码数据的应用程序,但我无法让Android的MediaCodec输出任何内容。我正在按照https://stackoverflow.com/a/7668578/10788248对RTP数据包进行解包 在编码帧被重新组装后,我将它们输入到出列的输入缓冲区中。 当我对输入缓冲区进行排队时,我不会得到任何错误,但是解码器的回调从来不会调用onOutputBuffer
我正在尝试使用c中的ffmpeg将视频文件解复用到视频部分(h264、mpeg4、h265、vp8等)和音频部分(mp3、aac、ac3等)以及字幕部分(srt)中。 音频部分很好,并在我所有的媒体播放器上播放,字幕部分也一样。然而,视频部分没有出现错误,并保存到了。h264文件,但当我使用ffprobe检查它或ffplay播放它时,它总是给出错误“处理输入时发现无效数据”。 下面的代码 编辑2我