MSE 流媒体录取的的问题

2022-12-05 12:01:35 +08:00
 acbot

MediaSource.prototype.addSourceBuffer = function (mime) { ... }

目前很多油猴脚本通过上述代码实现网页 m3u8 视频录取,测试过几个脚本基本上录取视频都没有问题,但是音频方面大多时候有问题。在不修改 video 标签 playbackRate 属性的情况下,音频部分脚本在部分网页能正常录取(不失真);但修改 video 标签的 playbackRate 属性的情况下(加速播放),基本音频都失真了,请问这个原因是什么:

  1. 本身这种录取实现就有问题,比如:包顺序,或者说要相应的设置音频 playbackRate 等
  2. 因为录取后音频和视频是分开的,那么有没有可能是 mp4a 格式的音频在其他播放器解码问题造成的失真,因为 PotPlayer 播放好像不失真
1196 次点击
所在节点    JavaScript
9 条回复
mxT52CRuqR6o5
2022-12-05 12:35:53 +08:00
不失真是因为用特殊算法处理过了,原始音频直接在时域上变速必失真的
acbot
2022-12-05 13:17:43 +08:00
@mxT52CRuqR6o5 "...原始音频直接在时域上变速必失真的.." 没太看懂,能说详细一点吗!加速播放过程仅仅是为了把视频音频读取到本地,这个过程加速音频失真很正常,我说的是缓存的音频文件也是失真的,而同样加速播放视频缓存文件确实正常的
wanacry
2022-12-05 13:52:31 +08:00
可能的原因是,在修改 video 标签的 playbackRate 属性之后,音频部分没有相应地调整其采样率和帧率,导致在播放器中解码时出现失真。这种情况下,视频部分可能会正常播放,但是音频部分可能会出现失真的情况。为了避免这种情况的发生,需要在修改 video 标签的 playbackRate 属性之后,相应地调整音频采样率和帧率,以保证音频能够正常播放。
hu8245
2022-12-05 15:08:20 +08:00
音频倍速必须重采样才能不失真,你直接拿肯定有问题啊。1 楼说的是正确
acbot
2022-12-05 15:25:54 +08:00
@hu8245
@wanacry

代码如下,应该在什么位置调整呢?

(function (addSourceBuffer) {
MediaSource.prototype.addSourceBuffer = function (mime) {
console.log(mime)
switch (mime.substr(0, 5)){
case "audio":
window.ams = addSourceBuffer.call(this, mime);
return window.ams
window.audioBuffer = [];
break;
case "video":
window.vms = addSourceBuffer.call(this, mime);
return window.vms
window.videoBuffer = [];
break;
default:
return addSourceBuffer.call(this, mime);
}
};
})(MediaSource.prototype.addSourceBuffer);

window.videoBuffer = [];
window.audioBuffer = [];

(function (appendBuffer) {
SourceBuffer.prototype.appendBuffer = function (source) {
if(this == window.ams){
console.log("audio buffer get")
window.audioBuffer[window.audioBuffer.length] = source
}
if(this == window.vms){
console.log("video buffer get")
window.videoBuffer[window.videoBuffer.length] = source
}
appendBuffer.call(this, source);
};
})(SourceBuffer.prototype.appendBuffer);
wanacry
2022-12-05 15:58:59 +08:00
在这段代码中,可以在 MediaSource.prototype.addSourceBuffer 函数中添加调整逻辑,例如在区分不同 mime 类型后,根据当前 mime 类型设置不同的播放速度,从而解决音频失真问题。

具体代码如下:

(function (addSourceBuffer) {
MediaSource.prototype.addSourceBuffer = function (mime) {
console.log(mime)
switch (mime.substr(0, 5)){
case "audio":
// 设置音频播放速度
window.ams = addSourceBuffer.call(this, mime);
ams.playbackRate = 1;
return window.ams
window.audioBuffer = [];
break;
case "video":
window.vms = addSourceBuffer.call(this, mime);
return window.vms
window.videoBuffer = [];
break;
default:
return addSourceBuffer.call(this, mime);
}
};
})(MediaSource.prototype.addSourceBuffer);

window.videoBuffer = [];
window.audioBuffer = [];

(function (appendBuffer) {
SourceBuffer.prototype.appendBuffer = function (source) {
if(this == window.ams){
console.log("audio buffer get")
window.audioBuffer[window.audioBuffer.length] = source
}
if(this == window.vms){
console.log("video buffer get")
window.videoBuffer[window.videoBuffer.length] = source
}
appendBuffer.call(this, source);
};
})(SourceBuffer.prototype.appendBuffer);
acbot
2022-12-05 17:01:24 +08:00
@wanacry 谢谢指教,我试试!
acbot
2022-12-05 17:04:30 +08:00
@wanacry 我还有一个问题,位什么视频不在这里添加处理逻辑 而直接设置标签的属性就可以呢,是音频和视频本身不一样,还是这里应该区获取音频,或者说 video 标签的 playbackRate 属性不能设置音频 比如:let video = document.querySelector('video'); video.playbackRate = 10
acbot
2022-12-10 11:07:02 +08:00
@wanacry 很遗憾 修改后音频直接是错误的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/900174

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX