<video id="video1" width="320" height="176" controls="controls">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.m4a" type="video/m4a">
</video>
我有一个无声视频,想在视频播放中添加他的音频文件
答案 0 :(得分:4)
这对我有用:
<meta charset="utf-8">
<video controls id="v" height="480" src="file.webm"></video>
<audio id="a" src="file.weba"></audio>
<script>
let v = document.getElementById('v');
let a = document.getElementById('a');
v.onpause = () => a.pause();
v.onplay = () => a.play();
v.onseeked = () => a.currentTime = v.currentTime;
</script>
控件在视频元素上,音频元素会响应视频播放, 停下来寻找。在这个例子中音量控制不起作用,所以你可以 要么添加该代码,要么只使用系统音量控制。
答案 1 :(得分:3)
MediaSource API 允许我们做到这一点。
请注意,要使其正常工作,您需要以与该 API 兼容的方式准备媒体资产。仔细阅读this MDN article,它很好地解释了如何执行此操作。
拥有资产后,剩下的就很简单了:
(async() => {
const fetching = Promise.all( [
// the video "only" file
fetchData( "https://dl.dropboxusercontent.com/s/u9ycdfwy8fig4dl/bbb_video.mp4" ),
// the audio "only" file
fetchData( "https://dl.dropboxusercontent.com/s/rj4dh32vxwi1iv5/bbb_audio.mp4" )
] );
const video_mime = "video/mp4; codecs=avc1.64000c";
const audio_mime = "audio/mp4; codecs=mp4a.40.2";
if(
!MediaSource.isTypeSupported( video_mime ) ||
!MediaSource.isTypeSupported( audio_mime )
) {
throw "unsupported codecs";
}
const source = new MediaSource();
document.querySelector( "video" ).src = URL.createObjectURL( source );
await waitForEvent( source, "sourceopen" );
const video_buffer = source.addSourceBuffer( video_mime );
const audio_buffer = source.addSourceBuffer( audio_mime );
video_buffer.mode = audio_buffer.mode = "sequence";
const [ video_data, audio_data ] = await fetching;
// There is a 'variable' limit as to how much
// data we can append in on go, 10MB seems quite safe
const chunk_size = 10 * 1024 * 1024;
let i = 0;
while (
i < video_data.length &&
i < audio_data.length
) {
const next_i = i + chunk_size;
const events = Promise.all( [
waitForEvent( video_buffer, "updateend" ),
waitForEvent( audio_buffer, "updateend" )
] );
video_buffer.appendBuffer( video_data.subarray( i, next_i ) );
audio_buffer.appendBuffer( audio_data.subarray( i, next_i ) );
await events;
i = next_i;
}
source.endOfStream();
})().catch( console.error );
function fetchData( url ) {
return fetch( url )
.then( (resp) => resp.ok && resp.arrayBuffer() )
// we return an Uint8 view to be able to do a zero-cost subarray()
.then( (buf) => new Uint8Array( buf ) );
}
function waitForEvent( target, event_name ) {
return new Promise( (res) => {
target.addEventListener( event_name, res, { once: true } );
} );
}
<video controls></video>