我已使用 <video>
在网页中嵌入了 DASH 视频标签。该内容有多个音轨。我想支持音轨更改。
我用过audioTracks[i].enable
选择音轨的功能。但音轨没有改变。
if (selected == i) {
audioTracks[i].enable = TRUE;
}
- 这是正确的方法吗?
- 还有其他方法可以更改 DASH(.mpd) 内容的音轨吗?
通过音轨更改,我的意思是启动一个可以传播到较低级别的音轨更改事件。本身不实现轨道变更。
我进一步尝试,
video标签的audioLanguage和lang属性为
document.getElementById(id).lang = selectedIndex;
和
document.getElementById(id).audioLanguage = selectedIndex;
即使这似乎也不起作用。
更清楚地说,正如 @Svenskunganka audioTracks[i].enable=TRUE;
的回答中提到的那样所使用的 Chromium 版本不支持。
那么,有没有其他方法可以做audioTracks[i].enable=TRUE
确实如此。
我不想实现跟踪更改功能。这里的要求只是向浏览器指示跟踪更改。
EDIT
:
正如我们在 https://www.w3schools.com/tags/av_prop_audiotracks.asp 中看到的那样。 Chrome 不支持此属性。那么指示必须更改轨道的替代方法是什么?
还有其他办法吗?或者audioTrack是唯一的方法(据我目前从搜索中了解到的)?
最佳答案
您可以请求.mpd
文件使用 fetch()
或XMLHttpRequest()
,阅读application/dash+xml
使用.text()
作为文本响应或.responseText
,将文本传递给DOMParser()
实例.parseFromString()
创建 #document
,迭代AdaptationSet
document.documentElement
的子节点Period
元素,使用.querySelector()
获取Representation
子节点则得到BaseURL
Representation
的子节点,其中 URL 为 .textContent
至少在引用的文件处具有同一目录中文件的路径。
我们还可以选择视频URL,使用Promise.all()
加载和播放视频和音频轨道,以便能够调用 HTMLMediaElement.captureStream()
,我们.clone()
并传递至resolve()
的Promise
构造函数,位于链接 .then()
调用.addTrack()
在MediaStream()
上每个轨道的实例,然后设置 <video>
.srcObject
到MediaStream
包含音频和视频轨道。
const video = document.querySelector("video");
const mediaStream = new MediaStream();
const url = "https://dash.akamaized.net/dash264/TestCases/10a/1/"
const mpd = "iis_forest_short_poem_multi_lang_480p_single_adapt_aaclc_sidx.mpd";
const avc = [];
video.oncanplay = video.play;
fetch(`${url}${mpd}`)
.then(response => response.text())
.then(text => {
const parser = new DOMParser();
const xml = parser.parseFromString(text, "application/xml");
const period = xml.documentElement;
const tracks = period.querySelectorAll("AdaptationSet");
for (let track of tracks) {
const representation = track.querySelector("Representation");
const {textContent:currentTrack} = representation.querySelector("BaseURL");
console.log(currentTrack);
// filter for specific track here, for example
// where "english" is included within `.textContent` of node
if (/english/i.test(currentTrack) || /avc/.test(currentTrack)) {
avc.push(`${url}${currentTrack}`);
}
}
Promise.all(avc.map(media => {
return new Promise(resolve => {
let v = document.createElement("video");
v.src = media;
v.volume = 0.5;
v.muted = true;
v.oncanplay = () => {
v.play();
resolve({
currentMedia:v
, stream:v.captureStream().clone().getTracks()[0]
})
}
})
}))
.then(tracks_ => {
for (let {stream, currentMedia} of tracks_) {
mediaStream.addTrack(stream);
currentMedia.muted = false;
}
video.srcObject = mediaStream;
})
})
<video controls></video>
关于javascript - 如何在 DASH 内容的 <video> 标签中启用音轨更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45560072/