代码之家  ›  专栏  ›  技术社区  ›  Arcades

如何用opentok传输音频文件?

  •  2
  • Arcades  · 技术社区  · 7 年前

    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 回复  |  直到 7 年前
        1
  •  3
  •   aiham    6 年前

    更新: videoSource audioSource 提供给的属性 OT.initPublisher ,请参阅文档: https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher

    https://github.com/opentok/opentok-web-samples/tree/master/Publish-Canvas

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


    旧答案:

    官方支持的API目前不可能做到这一点,但有一种方法可以做到这一点。

    请参阅TokBox博客中关于相机过滤器的帖子: https://tokbox.com/blog/camera-filters-in-opentok-for-web/

    https://github.com/aullman/opentok-camera-filters/blob/master/src/mock-get-user-media.js

    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的正式支持。

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

        2
  •  0
  •   Arcades    7 年前

    因此,我们用这段代码制作了一个不同的文件,该文件在我们的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函数,你知道我们的代码出了什么问题吗?