如何使用 opentok 流式传输音频文件?
How to stream audio file with opentok?
在 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);
像这样,我可以有一个带有声音和音乐的流,但是如何将这个流发送给发布者?有可能还是有其他方法可以做到这一点?
更新: 现在有一个官方方法可以做到这一点,使用提供给 OT.initPublisher
的 videoSource
和 audioSource
属性,拜托请参阅文档:https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher
这是一个如何将 canvas 元素流式传输为视频轨道的示例:https://github.com/opentok/opentok-web-samples/tree/master/Publish-Canvas
您可以应用相同的技术来流式传输音轨。
旧答案:
官方支持的 API 目前无法实现,但有办法做到。
请参阅 TokBox 博客 post 关于相机滤镜:https://tokbox.com/blog/camera-filters-in-opentok-for-web/
为了在流到达 OpenTok JS SDK 之前修改流,我们使用 mockGetUserMedia 函数拦截流:
https://github.com/aullman/opentok-camera-filters/blob/master/src/mock-get-user-media.js
您可以调用带有混音功能的 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;
});
在我们的 angular 中,我们初始化会话,创建发布者并发布它但得到错误:
Uncaught DOMException: Failed to execute 'createMediaElementSource' on 'BaseAudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode.
这个错误,我认为是抛出的,因为函数执行了两次。 js什么时候加载,什么时候发布。
我不确定如何使用这个 mockGetUserMedia 函数,你知道我们的代码有什么问题吗?
编辑
我们让它在一些 if 条件下工作。非常感谢你,非常感谢。
在 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);
像这样,我可以有一个带有声音和音乐的流,但是如何将这个流发送给发布者?有可能还是有其他方法可以做到这一点?
更新: 现在有一个官方方法可以做到这一点,使用提供给 OT.initPublisher
的 videoSource
和 audioSource
属性,拜托请参阅文档:https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher
这是一个如何将 canvas 元素流式传输为视频轨道的示例:https://github.com/opentok/opentok-web-samples/tree/master/Publish-Canvas
您可以应用相同的技术来流式传输音轨。
旧答案:
官方支持的 API 目前无法实现,但有办法做到。
请参阅 TokBox 博客 post 关于相机滤镜:https://tokbox.com/blog/camera-filters-in-opentok-for-web/
为了在流到达 OpenTok JS SDK 之前修改流,我们使用 mockGetUserMedia 函数拦截流:
https://github.com/aullman/opentok-camera-filters/blob/master/src/mock-get-user-media.js
您可以调用带有混音功能的 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;
});
在我们的 angular 中,我们初始化会话,创建发布者并发布它但得到错误:
Uncaught DOMException: Failed to execute 'createMediaElementSource' on 'BaseAudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode.
这个错误,我认为是抛出的,因为函数执行了两次。 js什么时候加载,什么时候发布。
我不确定如何使用这个 mockGetUserMedia 函数,你知道我们的代码有什么问题吗?
编辑
我们让它在一些 if 条件下工作。非常感谢你,非常感谢。