StreamTrack's readyState is getting changed to ended, just before playing the stream (MediaStream - MediaStreamTrack - WebRTC)

走远了吗. 提交于 2019-12-11 08:14:44

问题


The jsfiddle (https://jsfiddle.net/kalyansai99/mm1b74uy/22/) contains code where the user can toggle between front and back camera of the mobile.

In few mobiles its working fine (Moto g5 plus, Moto E3 and so on - Chrome Browser) and in few mobiles (Mi Redimi Note 4 - Chrome Browser) when I am switching to back camera, initially the stream is loading with a track of "readyState" as "live". But when i am about to play the stream in video player, the "readyState" is getting changed to "ended" and black screen is been shown on the video tag.

Not sure whats happening. Any clues?

JSFiddle Code

var player = document.getElementById('player');
var flipBtn = document.getElementById('flipBtn');
var deviceIdMap = {};
var front;

var constraints = {
    audio: false,
    video: {
        frameRate: 1000
    }
};

var gotDevices = function (deviceList) {
    var length = deviceList.length;
    console.log(deviceList);
    for (var i = 0; i < length; i++) {
        var deviceInfo = deviceList[i];
        if (deviceInfo.kind === 'videoinput') {
            if (deviceInfo.label.indexOf('front') !== -1) {
                deviceIdMap.front = deviceInfo.deviceId;
            } else if (deviceInfo.label.indexOf('back') !== -1) {
                deviceIdMap.back = deviceInfo.deviceId;
            }
        }
    }
    if (deviceIdMap.front) {
        constraints.video.deviceId = {exact: deviceIdMap.front};
        front = true;
    } else if (deviceIdMap.back) {
        constraints.video.deviceId = {exact: deviceIdMap.back};
        front = false;
    }
    console.log('deviceIdMap - ', deviceIdMap);
};

var handleError = function (error) {
    console.log('navigator.getUserMedia error: ', error);
};

function handleSuccess(stream) {
    window.stream = stream;
    // this is a video track as there is no audio track
    console.log("Track - ", window.stream.getTracks()[0]);
    console.log('Ready State - ', window.stream.getTracks()[0].readyState);
    if (window.URL) {
        player.src = window.URL.createObjectURL(stream);
    } else {
        player.src = stream;
    }
    player.onloadedmetadata = function (e) {
    		console.log('Ready State - 3', window.stream.getTracks()[0].readyState);
        player.play();
        console.log('Ready State - 4', window.stream.getTracks()[0].readyState);
    }
    console.log('Ready State - 2', window.stream.getTracks()[0].readyState);
}

navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);

flipBtn.addEventListener('click', function () {
		if (window.stream) {
      window.stream.getTracks().forEach(function(track) {
        track.stop();
      });
    }
  	if (front) {
      constraints.video.deviceId = {exact: deviceIdMap.back};
    } else {
      constraints.video.deviceId = {exact: deviceIdMap.front};
    }
  	front = !front;
  	navigator.getUserMedia(constraints, handleSuccess, handleError);
}, false);

console.log(constraints);
navigator.getUserMedia(constraints, handleSuccess, handleError);
#player {
  width: 320px;
}

#flipBtn {
  width: 150px;
  height: 50px;
}
<video id="player" autoplay></video>

<div>
  <button id="flipBtn">
      Flip Camera
  </button>
</div>

回答1:


Replace track.stop() to track.enabled=false and when adding track to the stream, enable it back using track.enabled=true

The MediaStream.readyState property is changed to "ended" when we stop the track and can never be used again. Therefore its not wise to use stop. For more reference:

https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/readyState

https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/stop



来源:https://stackoverflow.com/questions/44569562/streamtracks-readystate-is-getting-changed-to-ended-just-before-playing-the-st

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!