Permalink
Browse files

latest commit

  • Loading branch information...
muaz-khan committed Nov 28, 2016
1 parent b9bce6d commit c8e0e3862fb10c561b3d49e230cf13193af6a96f

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,286 @@
<!--
> Muaz Khan - https://github.com/muaz-khan
> MIT License - https://www.webrtc-experiment.com/licence/
> Experiments - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/Pre-recorded-Media-Streaming
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Pre-recorded media streaming ® Muaz Khan</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="author" type="text/html" href="https://plus.google.com/100325991024054712503">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
<style>
p { padding: .8em; }
video {
vertical-align: top;
width: 30%;
}
input {
border: 1px solid #d9d9d9;
border-radius: 1px;
font-size: 2em;
margin: .2em;
}
li {
border-bottom: 1px solid rgb(189, 189, 189);
border-left: 1px solid rgb(189, 189, 189);
padding: .5em;
}
code {
color: red;
font-family: inherit;
}
</style>
<script>
document.createElement('article');
document.createElement('footer');
</script>
<script src="https://cdn.webrtc-experiment.com/firebase.js"> </script>
<script src="https://cdn.webrtc-experiment.com/streamer.js"> </script>
</head>
<body>
<article>
<header style="text-align: center;">
<header style="text-align: center;">
<h1>
<a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/Pre-recorded-Media-Streaming" target="_blank">Pre-recorded media streaming</a> ®
<a href="https://github.com/muaz-khan" target="_blank">Muaz Khan</a>
</h1>
<p>
<a href="https://www.webrtc-experiment.com/">HOME</a>
<span> &copy; </span>
<a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
.
<a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
.
<a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
.
<a href="https://github.com/muaz-khan/WebRTC-Experiment/issues?state=open" target="_blank">Latest issues</a>
.
<a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">What's New?</a>
</p>
</header>
<div class="github-stargazers"></div>
<section class="experiment" style="text-align: center;">
<video autoplay poster="https://pbs.twimg.com/profile_images/458943715046727680/rh9nRmeW_400x400.png"></video>
<div>
<a href="https://googledrive.com/host/0B6GWd_dUUTT8RzVSRVU2MlIxcm8/Pre-recorded-Media-Streaming/WebM-file-to-stream-as-pre-recorded-media.webm" title="Download WebM file to stream as pre-recorded media" download="WebM-file-to-stream-as-pre-recorded-media.webm" target="_blank">Download WebM video</a>
<input type="file" title="Select WebM file / Size must be less than 800KB">
</div>
</section>
<script>
var streamer = new Streamer();
</script>
<script>
/* pre-recorded media sender */
streamer.push = function(chunk) {
firebase.push(chunk);
};
document.querySelector('input[type=file]').onchange = function() {
streamer.stream(this.files[0]);
};
</script>
<script>
/* pre-recorded media receiver */
streamer.video = document.querySelector('video');
streamer.receive();
function onData(data) {
if (data.end) streamer.end();
else streamer.append(data);
}
</script>
<script>
/* socket.io to push chunks */
var channel = location.href.replace(/\/|:|#|\?|\$|\^|%|\.|`|~|!|@|\[|\||]|\|*. /g, '').split('\n').join('').split('\r').join('');
var firebaseURL = 'https://webrtc.firebaseIO.com/' + channel;
var firebase = new Firebase(firebaseURL);
firebase.on('child_added', function(data) {
var data = data.val();
onData(data);
});
firebase.onDisconnect().remove();
</script>
<section class="experiment">
<h2 class="header">How to stream your own video?</h2>
<pre>
&lt;script src="https://www.webrtc-experiment.com/streamer.js"&gt; &lt;/script&gt;
&lt;script&gt; var streamer = new Streamer(); &lt;/script&gt;
</pre>
</section>
<section class="experiment">
<h2 class="header">pre-recorded media sender instance</h2>
<pre>
&lt;script&gt;
streamer.push = function (chunk) {
socket.send(chunk);
};
document.querySelector('input[type=file]').onchange = function () {
streamer.stream(this.files[0]);
};
&lt;/script&gt;
</pre>
</section>
<section class="experiment">
<h2 class="header">pre-recorded media receiver instance</h2>
<pre>
&lt;script&gt;
streamer.video = document.querySelector('video');
streamer.receive();
function onData(data) {
if (data.end) streamer.end();
else streamer.append(data);
}
&lt;/script&gt;
</pre>
</section>
<section class="experiment">
<h2 class="header">socket.io/websocket to push chunks</h2>
<pre>
&lt;script&gt;
socket.onmessage = onData;
// or
socket.on('message', onData);
&lt;/script&gt;
</pre>
</section>
<section class="experiment">
<h2 class="header" style="line-height: 2;">Chrome &gt;=M28 (or Firefox with flag "media.mediasource.enabled=true") is mandatory to test this experiment.</h2>
<ol>
<li>Streaming pre-recorded video (media file)</li>
<li>Currently, using Firebase for streaming chunks of data because <strong>MediaSource</strong> APIs are only supported on chrome canary which has unreliable RTP (RTCDataChannel) streams. Note: SCTP data channels landed on chrome M >=30 under a flag.</li>
<li>Streaming WebM files only (in the moment!)</li>
<li>WebM file's size must be less than 1000KB; otherwise it will fail. It is a bug will be fixed soon.</li>
</ol>
</section>
<section class="experiment">
<h2 class="header">It is an early release!</h2>
<ol>
<li>This experiment is an early release. In future, RTCDataChannel APIs will be used to stream pre-recorded media in realtime! (until "<strong>video.captureStream</strong>" gets implemented. Note: Firefox implemented a prefixed version of captureStream API i.e. <code><strong>mozCaptureStreamUntilEnded</strong></code>)</li>
<li>MediaSource APIs are not made for streaming pre-recorded Medias, though!</li>
<li>Waiting for "<strong>video.captureStream</strong>" implementation that is proposed for pre-recorded media streaming, unfortunately still in draft!</li>
</ol>
</section>
<section class="experiment">
<h2 class="header">In
<a href="http://www.w3.org/TR/streamproc/" target="_blank" title="Unfortunately, we've to wait!">future</a>:</h2>
<pre>
partial interface HTMLMediaElement {
readonly attribute MediaStream stream;
MediaStream <strong title="This will return us MediaStream object that we can directly attach to peer connection.">captureStream</strong>();
MediaStream captureStreamUntilEnded();
readonly attribute boolean audioCaptured;
attribute any src;
};
</pre>
<p>
We <strong>will be able to</strong> get stream from video like this:
</p>
<pre>
video.src = 'your pre-recorded webm/etc. video';
var preRecordedStream = video.<strong title="This will return us MediaStream object that we can directly attach to peer connection.">captureStream</strong>();
peer.addStream ( preRecordedStream );
</pre>
</section>
<section class="experiment">
<h2 class="header">Other possibilities</h2>
<pre>
var videoStream = video.createMediaElementSource();
var audioStream = audio.createMediaElementSource();
</pre>
<p>
"createMediaElementSource" is also landed on chrome M >= 30. It is also useful for streaming pre-recorded medias.
</p>
</section>
<section class="experiment">
<h2 class="header">How this experiment works?</h2>
<ol>
<li>Getting access to WebM video file using File API</li>
<li>Reading it as <strong>array buffer</strong> using File Reader API</li>
<li>Splitting buffers in predefined small chunks; and posting/transmitting those chunks in a loop using Firebase.</li>
<li>As soon as other party receives first chunk; MediaSource API will start playing video without waiting for all chunks to be downloaded!</li>
<li>You can save/store/record those chunks in any database; because it is a typed array [<strong>Uint8Array</strong>].</li>
</ol>
</section>
<section class="experiment">
<h2 class="header">Let's say you want to:</h2>
<ol>
<li>Stream 5min to 7min of video data i.e. total two minutes of video data (over all sockets) from <strong>first</strong> WebM file.</li>
<li>Then, quickly you want to stream 17 to 19 minutes i.e. total two minutes of data from <strong>second</strong> WebM file.</li>
<li>Then you want to stream 11 to 15 minutes i.e. total 4 minutes of data from <strong>third</strong> WebM file.</li>
</ol>
<p>You can do all such things today!</p>
<p>In simple words; you can stream <strong>part of video</strong> from <strong>first</strong> WebM file; part of video from <strong>second</strong> WebM file and so on, in realtime!</p>
</section>
<section class="experiment own-widgets latest-commits">
<h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
<div id="github-commits"></div>
</section>
<section class="experiment">
<h2 class="header" id="feedback">Feedback</h2>
<div>
<textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
</div>
<button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left: 1em;">Enter your email too; if you want "direct" reply!</small>
</section>
</article>
<a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/Pre-recorded-Media-Streaming" class="fork-left"></a>
<footer>
<p>
<a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
© <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
<a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
</p>
</footer>
<!-- commits.js is useless for you! -->
<script src="https://cdn.webrtc-experiment.com/commits.js" async> </script>
</body>
</html>
Oops, something went wrong.

0 comments on commit c8e0e38

Please sign in to comment.