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

时间:2017-08-23 12:07:58

标签: webrtc opentok tokbox web-audio-api

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

例如,我这样做了:

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);

像这样,我可以拥有一个包含语音和音乐的流,但是如何将这个流添加到发布者?是否可能或有其他方法可以做到这一点?

2 个答案:

答案 0 :(得分:3)

更新:现在有一种官方方法可以使用提供给videoSource的{​​{1}}和audioSource属性,请参阅文档:{ {3}}

这是如何将canvas元素作为视频轨道流式传输的示例:https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher

您可以应用相同的技术来播放音轨。

旧答案:

官方支持的API目前无法实现,但有一种方法可以实现。

请参阅有关相机滤镜的TokBox博客文章:https://github.com/opentok/opentok-web-samples/tree/master/Publish-Canvas

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

https://tokbox.com/blog/camera-filters-in-opentok-for-web/

您可以使用可以混音的函数调用mockGetUserMedia。像这样:

OT.initPublisher

注意:我没有测试过这个功能,但它应该引导你朝着正确的方向前进。请记住,这种技术容易出错,而且TokBox没有正式支持。

我们目前正在开发一个新功能,可以启用此用例,但我无法估计何时可用。

答案 1 :(得分:0)

感谢您的帮助,但从今天早上起我们无法继续工作。

所以我们用这个代码创建了一个不同的文件,它在我们的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.

我认为这个错误是throw,因为函数执行了两次。当js加载时,以及我们发布时。

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

修改

我们使用了一些if条件。非常感谢你,非常感谢。