MediaSource.prototype.addSourceBuffer = function (mime) { ... }
目前很多油猴脚本通过上述代码实现网页 m3u8 视频录取,测试过几个脚本基本上录取视频都没有问题,但是音频方面大多时候有问题。在不修改 video 标签 playbackRate 属性的情况下,音频部分脚本在部分网页能正常录取(不失真);但修改 video 标签的 playbackRate 属性的情况下(加速播放),基本音频都失真了,请问这个原因是什么:
1
mxT52CRuqR6o5 2022-12-05 12:35:53 +08:00 via Android
不失真是因为用特殊算法处理过了,原始音频直接在时域上变速必失真的
|
2
acbot OP @mxT52CRuqR6o5 "...原始音频直接在时域上变速必失真的.." 没太看懂,能说详细一点吗!加速播放过程仅仅是为了把视频音频读取到本地,这个过程加速音频失真很正常,我说的是缓存的音频文件也是失真的,而同样加速播放视频缓存文件确实正常的
|
3
wanacry 2022-12-05 13:52:31 +08:00
可能的原因是,在修改 video 标签的 playbackRate 属性之后,音频部分没有相应地调整其采样率和帧率,导致在播放器中解码时出现失真。这种情况下,视频部分可能会正常播放,但是音频部分可能会出现失真的情况。为了避免这种情况的发生,需要在修改 video 标签的 playbackRate 属性之后,相应地调整音频采样率和帧率,以保证音频能够正常播放。
|
4
hu8245 2022-12-05 15:08:20 +08:00
音频倍速必须重采样才能不失真,你直接拿肯定有问题啊。1 楼说的是正确
|
5
acbot OP @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); |
6
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); |