Why does MediaRecorder fail to start? (error: there's no audio or video tracks available) RecordRTC

Why does MediaRecorder fail to start? (error: there's no audio or video tracks available) RecordRTC

更新:目前最好的假设是,这是由大型 school/university 网络以某种方式引起的——其他用户没有遇到这个问题。


我正在使用 RecordRTC 来录制音频。这依赖于 MediaRecorder。

第一次开始录制时,记录了这个(发现的)错误:

DOM exception: failed to execute start on Media recorder: The 
MediaRecorder failed to start because there are no audio or video 
tracks available

在此之前,RecordRTC 调用 MediaRecorder API:

Using recorderType:MediaStreamRecorder
Passing following config over MediaRecorder API.Object {audio: "true", mimeType: "audio/webm", checkForInactiveTracks: "true", type: "audio", initCallback: "[object Function]"}

这是代码中的回溯。它首先调用 startRecording(在 redux saga 中):

const recorder = yield select(getRecorder)
yield call(recorder.startRecording)

这是startRecording

startRecording = () => {

try {
  this.captureUserMedia((stream) => {
    try {
       this.rtcRecorder.startRecording()
     this.recording = true
    } catch (err) {
      sendEmail(err, "inner startRecording failed", "support@gmail.com")
      console.log("inner startRecording ERROR: ", err)
    }
  });
} catch (err) {
    sendEmail(err, "startRecording failed", "support@gmail.com")
    console.log("startRecording ERROR: ", err)
}

}

这里是 captureUserMedia

captureUserMedia(callback) {
 var params = { audio: true, video: false };

 navigator.getUserMedia(params, callback, (error) => {
   // alert(JSON.stringify(error));
   console.log('USER MEDIA ERROR::   ' + JSON.stringify(error))
   callback(null, error)
 });
};

错误似乎发生在这一行,特别是 startRecording

this.rtcRecorder.startRecording()

还有一些细节可能有助于解决此问题:

  1. Chrome version does not seem to be the problem: some users with v61.0.3163.100 have the problem, while others don't
    1. For the users who experience the problem, it seems to occur every time.
    2. Apparently, navigator.getUserMedia is deprecated, but it still should function— the complicated logic of the promise could be introducing a bug.

更新:

  1. The problem has happened to two users who were on large networks (A university network and a public school district network). It has not yet happened to any users who were on private home networks....

让我知道还有哪些其他信息会有所帮助,我会立即回复。谢谢你。

更新:

Muaz Khan 建议添加一个隐藏的音频元素以防止流和曲目被 stopped/released。这是在捕获流之前添加的附加代码(当记录器首次初始化时):

var hiddenAudio = document.createElement('audio');
hiddenAudio.srcObject = stream // this line is required to make sure stream tracks aren't stopped/released
hiddenAudio.muted = true
hiddenAudio.play()

更新 2:

但是还是不行。思考为什么这可能行不通:

  1. 我不确定 hiddenAudio HTML 元素是否真的持续存在并捕获流。 (它的范围可能不正确。)

我想知道 navigator.getUserMedia 的回调地狱中是否存在细微错误,并且使用较新的 navigator.mediaDevices getusermedia(依赖于承诺)会更容易理解。

另一种可能是记录器初始化时引入的错误——这里是:

initialize = (callback) => {

if (!!this.rtcRecorder) {
  console.log('Attempted to initialize an already initialized recorder but that\'s expected')
  return
}

console.log('initialize Recorder -- requestUserMedia')
this.captureUserMedia((stream, error) => {

  if (error) {
    console.log('!!errror capturing user media!!')
    return callback && callback(error)
  }

  // TODO: detect if system can play webms

  // <-- smaller filesize
  // this.rtcRecorder = RecordRTC(stream, { recorderType: RecordRTC.StereoAudioRecorder, bitsPerSecond: 30000, numberOfAudioChannels: 1, mimeType: 'audio/wav' });

  try {

    // the MUAZ KHAN edits
    var hiddenAudio = document.createElement('audio');
    hiddenAudio.srcObject = stream // this line is required to make sure stream tracks aren't stopped/released
    hiddenAudio.muted = true
    hiddenAudio.play()


    this.rtcRecorder = RecordRTC(stream,  { audio: 'true', mimeType: 'audio/webm', checkForInactiveTracks: 'true' });
    callback && callback(null)
    return true
  } catch (err) {
    sendEmail(err, "captureMedia (inner-most) startRecording failed", "support@gmail.com")
    console.log("captureMedia (inner-most) startRecording ERROR: ", err)
    callback && callback(null)
    return true
  }


});
};

再次感谢。

更新:

此处包括遇到此问题的两个用户的配置文件(都是大型 public school/university 网络)。私人家庭网络上的用户不会出现此问题:

当出现 getUserMedia 错误时,此代码将失败。变化

this.captureUserMedia((stream) => {

this.captureUserMedia((stream, err) => {

并处理正在设置的错误(当流为空时)。重现此问题的最简单方法可能是通过单击地址栏最右侧的相机图标来阻止权限。

问题出在需要访问流的 captureUserMedia 中:

captureUserMedia(callback) {
  var params = { audio: true, video: false };
  navigator.getUserMedia(params, (stream) => {
    callback(stream)
  }, (err) =>  {
    callback(null, err)
  })
  return
}