I've done a webcam directive that uses a service in AngularJS. I've used this example:
https://simpl.info/getusermedia/sources/
When I try the example in my tablet it works fine, but when I start my code in the tablet (Google Chrome), it gives me a couple of bugs.
Bug #1: I can't get the rear camera to work.
Bug #2: When I start the camera directive, it only shows me the first frame of the stream and then it halts. Although, when I flip to the rear camera (that doesn't work) and then flip back, it gives me the stream.
Anyone got any ideas about what I might be doing wrong? I've tried a lot of stuff.
Webcam directive:
link: function postLink($scope, element) {
var videoSources = [];
MediaStreamTrack.getSources(function(mediaSources) {
for (var i = 0; i < mediaSources.length; i++)
{
if (mediaSources[i].kind == 'video')
{
videoSources.push(mediaSources[i].id);
}
}
if (videoSources.length > 1){ $scope.$emit('multipleVideoSources'); }
initCamera(0);
});
// Elements
var videoElement = element.find('video')[0];
// Stream
function streaming(stream) {
$scope.$apply(function(){
videoElement.src = stream;
videoElement.play();
});
}
// Check ready state
function checkReadyState(){
if (videoElement.readyState == 4)
{
$interval.cancel(interval);
$scope.$emit('videoStreaming');
}
}
var interval = $interval(checkReadyState, 1000);
// Init
$scope.$on('init', function(event, stream){
streaming(stream);
});
// Switch camera
$scope.$on('switchCamera', function(event, cameraIndex){
initCamera(cameraIndex);
});
// Init via Service
function initCamera(cameraIndex)
{
var constraints = {
audio: false,
video: {
optional: [{ sourceId: videoSources[cameraIndex] }]
}
};
camera.setup(constraints, camera.onSuccess, camera.onError);
}
}
Camera service:
.service('camera', function($rootScope) {
// Setup of stream
this.init = false;
this.onError = function(error){
console.log(error);
alert('Camera error');
};
this.onSuccess = function(stream){
window.stream = stream;
stream = window.URL.createObjectURL(stream);
$rootScope.$broadcast('init', stream);
};
this.setup = function(constraint){
navigator.getMedia(constraint, this.onSuccess, this.onError);
this.init = true;
};
On my laptop this works fine, although I can only test with one video source (as it only has one).
Bug #2 solved by not do videoStream.play() until it has a readyState of 4.
Bug #1 solved by moving window in to the directive and not using the service. Then calling the following code within initCamera function:
if (!!window.stream) {
videoElement.src = null;
window.stream.stop();
}