javascript - 如何在 DASH 内容的 <video> 标签中启用音轨更改?

标签 javascript html html5-video chromium mpeg-dash

我已使用 <video> 在网页中嵌入了 DASH 视频标签。该内容有多个音轨。我想支持音轨更改。
我用过audioTracks[i].enable选择音轨的功能。但音轨没有改变。

if (selected == i) {
    audioTracks[i].enable = TRUE;
}
  1. 这是正确的方法吗?
  2. 还有其他方法可以更改 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> .srcObjectMediaStream包含音频和视频轨道。

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/

相关文章:

javascript - 确定 2 个日期之间耗时

javascript - 比较字符串并得到最终差异

html - 响应式和全高侧边栏

javascript - HTML5 : Video tag change video time display from MM:SS to HH:MM:SS

javascript - 图像可见性一

javascript - 事件 anchor 链接在滚动/单击时未在固定导航上正确设置

html - ios 中的正则表达式提取 href url 并丢弃 anchor 标记的其余部分?

javascript - 捕获 <webview> 中由 HTML 标签引起的 "Failed to load resources"错误

javascript - HTML5 视频函数

javascript - 当我点击按钮时,视频不会弹出