Webrtc 如何使用opentok传输音频文件?

Webrtc 如何使用opentok传输音频文件?,webrtc,opentok,tokbox,web-audio-api,Webrtc,Opentok,Tokbox,Web Audio Api,在opentok中,使用OT.initPublisher,您只能将deviceId传递给音频源。有人知道流式传输音频文件的方法吗 例如,我做了以下工作: navigator.getUserMedia({audio: true, video: false}, function(stream) { var context = new AudioContext(); var microphone = context.createMediaStreamSource(stream);

在opentok中,使用OT.initPublisher,您只能将deviceId传递给音频源。有人知道流式传输音频文件的方法吗

例如,我做了以下工作:

navigator.getUserMedia({audio: true, video: false},
function(stream) {
    var context = new AudioContext();
    var microphone = context.createMediaStreamSource(stream);
    var backgroundMusic = context.createMediaElementSource(document.getElementById("song"));
    var mixedOutput = context.createMediaStreamDestination();
    microphone.connect(mixedOutput);
    backgroundMusic.connect(mixedOutput);
},
handleError);

像这样,我可以有一个声音流和我的音乐,但如何把这个流到出版商?有没有其他方法可以做到这一点?

更新:现在有一种官方方法可以做到这一点,使用提供给
OT.initPublisher
videoSource
audioSource
属性,请参阅文档:

这是一个如何将画布元素流化为视频曲目的示例:

您可以将相同的技术应用于流式播放音频曲目


旧答案:

官方支持的API目前无法实现这一点,但有一种方法可以做到这一点

请参阅TokBox关于相机过滤器的博客帖子:

为了在流到达OpenTok JS SDK之前修改流,我们使用mockGetUserMedia函数拦截流:

您可以使用一个函数调用mockGetUserMedia来进行音频混合。大概是这样的:

mockGetUserMedia(function(originalStream) {
  var context = new AudioContext();
  var microphone = context.createMediaStreamSource(originalStream);
  var backgroundMusic = context.createMediaElementSource(document.getElementById("song"));
  var mixedOutput = context.createMediaStreamDestination();
  microphone.connect(mixedOutput);
  backgroundMusic.connect(mixedOutput);

  var stream = mixedOutput.stream;
  originalStream.getVideoTracks().map(function(track) {
    stream.addTrack(track);
  });
  return stream;
});
注意:我还没有测试过这个功能,但它应该会引导您走向正确的方向。请记住,这种技术很容易出错,TokBox不支持这种技术


我们目前正在开发一项新功能,该功能将启用此用例,但我无法给出它何时可用的时间估计。

感谢您的帮助,但从今天早上起我们无法使其正常工作

因此,我们用这段代码制作了一个不同的文件,它在html中的opentok库之前实现:

function mockGetUserMedia(mockOnStreamAvailable) {
  var oldGetUserMedia = void 0;
  if (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
    oldGetUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
    navigator.webkitGetUserMedia = navigator.getUserMedia = navigator.mozGetUserMedia = function getUserMedia(constraints, onStreamAvailable, onStreamAvailableError, onAccessDialogOpened, onAccessDialogClosed, onAccessDenied) {
      return oldGetUserMedia.call(navigator, constraints, function (stream) {
        onStreamAvailable(mockOnStreamAvailable(stream));
      }, onStreamAvailableError, onAccessDialogOpened, onAccessDialogClosed, onAccessDenied);
    };
  } else {
    console.warn('Could not find getUserMedia function to mock out');
  }
};

mockGetUserMedia(function(stream) {
    var context = new AudioContext();
    var bgMusic = context.createMediaElementSource(document.getElementById("song"));
    var microphone = context.createMediaStreamSource(stream);
    var destination = context.createMediaStreamDestination();
    bgMusic.connect(destination);
    microphone.connect(destination);
    var mixedStream = destination.stream;
    stream.getVideoTracks().map(function(track) {
       mixedStream.addTrack(track);
    });
    return mixedStream;
});
在我们的示例中,我们初始化会话,创建一个发布者并发布它,但得到错误:

Uncaught DOMException: Failed to execute 'createMediaElementSource' on 'BaseAudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode.
我认为这个错误是抛出的,因为函数执行了两次。当js加载时,以及当我们发布时

我不知道如何使用这个mockGetUserMedia函数,你知道我们的代码有什么问题吗

编辑
我们让它在一定条件下工作。非常感谢,非常感谢。

这将在v2.12中出现。请参阅最新版本的