Stream static video file through webrtc - webrtc

what I am trying to accomplish is to have on my page audio and video file. And then send them through webrtc. I managed to do this with audio using web audio api like this.
HTML:
<audio id="audio">
<source src="../assets/outfoxing.mp3" />
</audio>
JS:
const audioElement = document.getElementById("audio");
const incomingSource = audioContext.createMediaElementSource(audioElement);
const outgoingStream = audioContext.createMediaStreamDestination();
incomingSource.connect(outgoingStream);
const outgoingTrack = outgoingStream.stream.getAudioTracks()[0];
audioElement.play();
await this.sendTransport.produce({ track: outgoingTrack });
For webrtc I am using mediasoup
Now I want to do the same with the video. But there is no such thing like web video api so I am stuck. How can I accomplish this task.

There are some limitations, but you could refer to this sample implementation.
It uses the captureStream() method.

Related

How to save video stream recorded from webcam in safari browser?

Safari doesn't support MediaRecorder to listen to the stream from WebCam like the below code.
This works perfectly in Chrome and I'm able to convert the blob to a webm video file.
if(navigator.mediaDevices.getUserMedia)
{
navigator.mediaDevices.getUserMedia({video: true, audio: true}).then (stream => {
videoRef.srcObject = stream
mediaRecorder.value = new MediaRecorder(stream, {mimeType: 'video/webm; codecs=vp8,opus'})
mediaRecorder.value.addEventListener('dataavailable', function(e) {
blobs.push(e.data)
})
})
}
})
I need to save the video streamed from webcam in my server. What should be the approach to achieve the same in Safari?
I researched a lot, saw a similar question. But there was no proper solution given.
Could someone guide to a tutorial on how to achieve this using WebRTC if needed?

Webrtc disable track doesn't turn off webcam

I am trying to implement a toggle video feature using webRTC. Refer to the following code:
<video id="remote" autoPlay></video>
<button onclick="toggleVideo()">Toggle video</button>
let localVideo = document.querySelector('#local');
const toggleVideo = () => {
localVideo.srcObject.getVideoTracks()[0].enabled = !localVideo.srcObject.getVideoTracks()[0].enabled
}
This turns off video as well as webcam indicator in firefox but not in chrome. Chrome only turns off the video.
According to MDN docs,
If the MediaStreamTrack represents the video input from a camera, disabling the track by setting enabled to false also updates device activity indicators to show that the camera is not currently recording or streaming. For example, the green "in use" light next to the camera in iMac and MacBook computers turns off while the track is muted in this way.
MDN docs
Is there any other workaround?

broadcast a web-cam to (YouTube, Twitch , facebook) using HTML5 and WebRTC

I'm working on a project where i need to broadcast a live video on youtube, twitch , Facebook or other platforms from my website using HTML5 , rtmp , webrtc, nodejs....
so instead of going to youtube and start a live video, i want to start the video from my website
but im new to webrtc and live streaming and i don't know what to do or how to start this so please if anyone have any ideas or suggestions about how to do this please contact me or leave a comment here
this is what i did
SERVER SIDE (NodeJs)
io.on('connection', (socket) =>{
socket.on('stream', stream =>{
console.log(stream)
socket.broadcast.emit('stream', stream);
});
})
Client Side
Html (video.html)
<div id="videos">
<video id="video" autoplay>
</video>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="js/video.js"></script>
Javascript (video.js)
var socket = io();
navigator.mediaDevices.getUserMedia({
video : true,
audio: true
})
.then(stream =>{
document.getElementById('video').srcObject = stream
socket.emit("stream", stream);
})
socket.on('stream', stream=>{
video = document.createElement("video")
video.srcObject = stream
video.setAttribute('autoplay')
document.getElementById("videos").appendChild(video)
})
You will need to do a WebRTC to RTMP bridge on your backend.
There are a lot of things to consider, but this is a common question so I threw together twitch. It is an example of doing this.

Is possible create a Real Time Multiplayer game web based?

I am trying to use the Google Play Game Services to create a multiplayer game based web, but I can't create the Rooms. Is possible use the Google play game services on web to use the real multiplayer?
<meta name="google-signin-clientid" content="32241234345-oklsdfhgiodf89789gfgfy9ym.apps.googleusercontent.com" />
<meta name="google-signin-cookiepolicy" content="single_host_origin" />
<meta name="google-signin-callback" content="signinCallback" />
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/games https://www.googleapis.com/auth/plus.login">
<!--meta name="google-signin-scope" content="https://www.googleapis.com/auth/games-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
<script src="https://apis.google.com/js/client:plusone.js"></script>
<script>
var appId = '0000000000';
var clientId = '0000000000-dfdsfsdfsdfsdgsdgfsdtodnjj8hq6hjm.apps.googleusercontent.com';
var apiKey = 'SDFGSDKjjk123123';
//var scopes = 'https://www.googleapis.com/auth/plus.me';
var scopes = 'https://www.googleapis.com/auth/games';
function create(){
gapi.client.request({
path: 'https://www.googleapis.com/games/v1/rooms/create',
method: 'POST',
callback: function(response) {
console.log(response);
}
});
return false;
}
The answer depends on whether or not you want the game to be in real time or not. If you are ok with a turn based multiplayer game then you can use the REST API.
For more info visit this link: https://developers.google.com/games/services/common/concepts/turnbasedMultiplayer
If you want multiplayer to be real-time then the answer is No. You currently can not do that with Googles API. It is only available on mobile.
Unfortunately only works with Android and iOS
The Google Play Games real-time multiplayer service is supported on
these platforms:
Android through the Google Play services SDK
iOS through the iOS SDK
https://developers.google.com/games/services/common/concepts/realtimeMultiplayer

Loading audio via a Blob URL fails in Safari

Following code works in Chrome (22.0) but not in Safari (6.0)
<!DOCTYPE html>
<html>
<head>
<script>
function onGo(e) {
var fr = new FileReader();
var file = document.getElementById("file").files[0];
fr.onload = function(e) {
var data = new Uint8Array(e.target.result);
var blob = new Blob([data], {type: 'audio/mpeg'});
var audio = document.createElement('audio');
audio.addEventListener('loadeddata', function(e) {
audio.play();
}, false);
audio.addEventListener('error', function(e) {
console.log('error!', e);
}, false);
audio.src = webkitURL.createObjectURL(blob);
};
fr.readAsArrayBuffer(file);
}
</script>
</head>
<body>
<input type="file" id="file" name="file" />
<input type="submit" id="go" onclick="onGo()" value="Go" />
</body>
</html>
In Safari, neither callback (loadeddata nor error) is called.
The content used is an mp3 file, which is normally played back with audio tag.
Is there any special care needed for Safari?
Many years later, I believe the example in the OP should work just fine. As long as you somehow set the mime type when creating the blob, like the OP does above with the type property of the options passed in:
new Blob([data], {type: 'audio/mpeg'});
You could also use a <source> element inside of an audio element and set the type attribute of the <source> element. I have an example of this here:
https://lastmjs.github.io/safari-object-url-test
And here is the code:
const response = await window.fetch('https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Alexander_Graham_Bell%27s_Voice.ogg/Alexander_Graham_Bell%27s_Voice.ogg.mp3');
const audioArrayBuffer = await response.arrayBuffer();
const audioBlob = new Blob([audioArrayBuffer]);
const audioObjectURL = window.URL.createObjectURL(audioBlob);
const audioElement = document.createElement('audio');
audioElement.setAttribute('controls', true);
document.body.appendChild(audioElement);
const sourceElement = document.createElement('source');
audioElement.appendChild(sourceElement);
sourceElement.src = audioObjectURL;
sourceElement.type = 'audio/mp3';
I prefer just setting the mime type of the blob when creating it. The <source> element src attribute/property cannot be updated dynamically.
I have the same problem, and I spend a couple days troubleshooting this already.
As pwray mentioned in this other post, Safari requires file extensions for media requests:
HTML5 Audio files fail to load in Safari
I tried to save my blob to a file, named it file.mp3 and Safari was able to load the audio that way, but after I renamed the file to have no extension (just "file"), it didn't load.
When I tried the url created from the blob in another tab in Safari:
url = webkitURL.createObjectURL(blob);
it download a file right away called "unknown", but when I tried the same thing in Chrome (also on Mac), it showed the content of the file in the browser (mp3 files start with ID3, then a bunch of non-readable characters).
I couldn't figure out yet how I could force the url made of blob to have an extension, because usually it looks like this:
blob:https://example.com/a7e38943-559c-43ea-b6dd-6820b70ca1e2
so the end of it looks like a session variable.
This is where I got stuck and I would really like to see a solution from some smart people here.
Thanks,
Steven
Sometimes, HTML5 audio can just stop loading without any apparent reason.
If you take a look to the Media Events (http://www.w3schools.com/tags/ref_eventattributes.asp) you´ll see an event called: "onStalled", the definition is "Script to be run when the browser is unable to fetch the media data for whatever reason" and it seems that it should be helpful for you.
Try listening for that event and reloading the file if necessary, with something like this:
audio.addEventListener('onstalled', function(e) {
audio.load();
}, false);
I hope it helps!
Just use source tag in audio.
<audio controls>
<source src="blob" type="blobType">
</audio>