Sending camera video from browser to server - html

Im trying out the new and exciting features of chrome canary 19.
I can basically grab the video from the web-cam and set it to a source element for a video tag.
<!DOCTYPE html>
<html>
<head>
<title>Camera capture</title>
<script>
var localStream;
var localStreamObjUrl;
window.onload = function() {
navigator.webkitGetUserMedia("audio, video", gotStream);
}
function gotStream(stream) {
localStream = stream;
localStreamObjUrl = webkitURL.createObjectURL(localStream);
var video = document.getElementById("selfView");
video.src = localStreamObjUrl;
}
</script>
</head>
<body>
<video id="selfView" autoplay audio=muted></video>
</body>
</html>
From the example at https://apprtc.appspot.com, we can grab the video and stream it to a peer...
My question is, can I avoid doing all the traversal to get a p2p connection and directly upload the video to a server? Id like to be able to relay the video stream instead of sending it p2p.

You need some kind of streaming media server on the back.
The process would be:
capture the feed
send it to the server
transcode to various client formats
manage the outbound streams
There are numerous free and paid varieties available:
nodejs(demo/POC)
wowza(paid)
chrome based
More about transcoding: xuggler
The 'swiss army knife' of media: ffmpeg
and so on.

I have developed video recording solutions for the better part of the last 5 years and contributed a lot to fixing video recording bugs in Red5.
On the desktop you can use a Flash client + a media server (Red5, Wowza, Adobe Media Server) and on the mobile you can use HTML Media Capture.
I gave a detailed answer on a similar question at Record video on browser and upload to LAMP server

You can try nimbb, in which they have Flash-based and HTML5 capturing. After that, you can push the video to Brightcove to transcode it to various clients format.
They have API integration. The only issue is the cost.

Related

HTML5 record moderate video quality for upload to be playable by Safari

I am creating a web-based mobile app where it should be possible to upload video-recordings.
There are two ways to achieve this:
Use input:
<input type="file" name="video" accept="video/*" capture></input>
Use RTC MediaRecorder:
var recordedBlobs = [];
function handleDataAvailable(event) {
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
}
var options = {
mimeType: 'video/webm',
audioBitsPerSecond : 128000,
videoBitsPerSecond : 2500000
}
mediaRecorder = new MediaRecorder(window.stream, options);
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(10);
While the first option always works the main problem is that it uses the build-in mobile camera application leaving us no control over quality, which again leads to potentially very large files (especially on android)
Second version gives us full control over quality and lets os create moderate file sizes that are size-wise acceptable as content in the application. iOS/Safari does not support this feature yet, but this is ok since iPhones record small files by default when started from the browser. So I can activate option 1 when the user-agent is iOS.
Now the problems:
First option would be fine if I could:
Control the video recording quality of the mobile application
Post-elaborate the recording to change the resolution before upload
The problem with option 2 is that only the .webm container type is supported, and Safari does not support this type.
So I'm a little stuck - right now it seems like my only option is to post-convert the incoming .webm files to .mp4 on the server as they are uploaded. But it seems to be a very CPU costly process on the server.
Any good ideas?
You can record as H.264 into a webm container. This is supported by Chrome.
var options = {mimeType: 'video/webm;codecs=h264'};
media_recorder = new MediaRecorder(stream, options);
Although it is an usual combination of video format and container - it is valid.
Now you could change H.264/webm into H.264/mp4 without transcoding the video stream using ffmepg (-vcodec copy).
You could also try re-wrapping from webm to mp4 client side in JavaScript using ffmpeg.js.

Play video files online sequentially without delay/buffering between videos

Is it possible to play video online that's made of two or more video files?
Since my original post wasn't clear enough, here's expanded explanation and question.
My site is hosted on Linux/Apache/PHP server. I have video files in FLV/F4V format. I can also convert them to other available formats if necessary. All videos have same aspect ratio and other parameters.
What I want is to build (or use if exist) online video player that plays video composed of multiple video files concatenated together in real-time, i.e. when user clicks to see a video.
For example, visitor comes to my site and sees video titled "Welcome" available to play. When he/she clicks to play that video, I take video files "Opening.f4v", "Welcome.f4v" and "Ending.f4v" and join/merge/concatenate them one after another to create one continuous video on the fly.
Resulting video looks like one video, with no visual clues, lags or even smallest observable delay between video parts. Basically what is done is some form of on-the-fly editing or pre-editing, and user sees the result. This resulting video is not saved on the server, it's just composed and played that way real-time.
Also, if possible, user shouldn't be made to wait for this merging to be over before he/she sees resulting video, but to be able to get first part of the video playing immediately, while merging is done simultaneously.
Is this possible with flash/actionscript, ffmpeg, html5 or some other online technology? I don't need explanation how it's possible, just a nod that it's possible and some links to further investigate.
Also, if one option is to use flash, what are alternatives for making this work when site is visited from iphone/ipad?
An approach that will work on some browsers currently, and on most browsers going forwards is to use the HTML5 Video Media Source Extension mechanism.
This essentially allows you replace a static 'src' file for a video in your HTML5 page, with a dynamic src buffer which you can then fill any way you want using your own Javascript code.
So you can write code to pre-buffer the second video when you get towards the end of the first video and then immediately start adding packets from the second video to the src right after the last packet for the first video.
In very high level terms this looks like:
Your HTML to insert the video where you want it in your page:
.
.
.
<div>
<video id="yourVideo1" controls="" autoplay="" width="320" height="240"></video>
</div>
.
.
.
Your Javascript to provide the source for your video:
//Get the video element
var videoElement = document.getElementById('yourVideo1');
//Create a 'MediaSource' and associate it with this video
var mediaSource = new MediaSource();
video.src = window.URL.createObjectURL(mediaSource);
//Add a listener to the MediaSource object to check for
//the video been opened. In this function you can add your
//code to get the get your videos from the servers and add
//'chunks' to the media source buffer
mediaSource.addEventListener('sourceopen', function(e) {
//Set the format of the source video
var mediaSourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
//Get your video from the web
while (not the end of your video playlist) {
...
//Stream video from server
...
//Add packets received to the media source bufer
mediaSourceBuffer.appendBuffer(receivedVideoPackets);
//If near end of video start fetching next video to
//avoid buffering delay
...
//If end of video go to next video in playlist
...
}
}, false);
Look at the HTML5 Rocks demo below to see this in action (for a slightly different usecase).
Given how tricky video manipulation is and the multitude of formats etc, it would be much easier for you if one of the established video players provided the functionality out of the box so I would still try their forums as mentioned in the comment, but at least you know it is technically possible.
The MSE spec is available here:
http://w3c.github.io/media-source/
And a good intro blog and demo is here (make sure your browser supports MSE - latest version of Chrome does):
http://updates.html5rocks.com/2011/11/Stream-video-using-the-MediaSource-API
You can find latest browser support here:
http://www.jwplayer.com/html5/mediasource/
Use two video elements, first visible and second display:none for buffering.
After first video playing, check currentPosition and currentDuration,
specify second video preloader prepare visible video player's buffer data.
First video element's SRC could be specified anytime for seamless playing.

HTML5 video loop doesn't work on Chrome (Sitefinity CMS)

I ran into this peculiar problem that I couldn't get HTML5 video to loop on my local development environment (ASP.NET + IIS7). The video autoplays just fine. My code looks like this:
<video id="frontpage-video" autoplay loop>
<source src="http://test-site:8084/video_mp4.mp4" type="video/mp4">
<source src="http://test-site:8084/video_webm.webm" type="video/webm">
</video>
If I change video source URLs to some publicly available URLs (for example to dropbox), loop works just fine. This is not a major problem since I think (hope) it will work once my site goes live and the video is publicly available.
My question is: Can I make the video loop if my video is not publicly available?
I couldn't find similar problems by googling. Could it be some kind of IIS setting that prevents videos to loop?
Update 1: The problem seems to occur only in Chrome. Firefox and IE works fine.
Update 2: It seems that the video will stop at the end but never returns true for element.ended
> document.getElementById('frontpage-video').duration;
< 16.12
> document.getElementById('frontpage-video').currentTime;
< 16.12
> document.getElementById('frontpage-video').ended;
< false
Update 3: Problem is either in IIS or in Telerik's Sitefinity CMS. Server should send a "206 Partial Content" status but instead it sends 200 OK. Has any Sitefinity users had this problem and know how to solve it?
It looks like your problem is that you're not using HTTP Byte Serving. Your server is sending a "200 OK" response, but it should be sending "206 Partial Content" along with these headers:
Accept-Ranges:bytes
Content-Range:bytes 0-1492370/1492371
The byte range request allows the browser to request only the portions of the file that it needs. So if you seek around, it can skip right to that point.
With the regular 200 response, you will usually at least find that you can't seek in the video. But, depending on how your video file is encoded and where in the file the metadata is placed, you may see more problems. Sometimes the file might not even play at all. WebM is usually more robust than MP4, which can be all over the place.
I don't know IIS well enough to tell you how to configure it, but try starting here:
http://blogs.visigo.com/chriscoulson/easy-handling-of-http-range-requests-in-asp-net/
Chrome/Opera can't loop the video if the video itself is not served with HTTP 206 Partial Content response but 200 OK instead.
The problem is that Sitefinity's storage providers do not support partial content (version 7.0). They are planning to implement this for the future.
At the moment the possible workaround is to use an external blob storage provider such as Azure, Amazon or ExternalFileSystem (ExternalFileSystemStorageProvider).
I got this information from Sitefinity's support team.
May be MIME type in IIS is not set up for MP4.
Open IIS, and locate you default page. You'll see MIME type in right pane.
Click Add and put field1=.mp4 and field2=video/mp4.
Restart IIS.
Hope this might work.
In your question, your video-element doesn't have the id frontpage-video (but i guess it's copy paste?)
check if the video end event is called in your webkit browsers, and if so, restart your video.
.
<script type='text/javascript'>
document.getElementById('frontpage-video').addEventListener('ended',myHandler,false);
function myHandler(e) {
if(!e) { e = window.event; }
//restart your video
}

How to amplify volume level of MediaStream using javascript

I am using video element of html5 for displaying video and audio streaming.
In older version of systems (laptops, pcs, etc), somtimes volume level is not good. so i want to amplify stream audio volume .
I made some hunt but didn't find any feasible solution.
Please provide me some links or some solution so that i can integrate that in my app
you can use timbre.js to add compression ( with gain, ie. amplification ) to the audio of your video track. Something like this:
// the source of your video file
var src = document.getElementById('video').firstElementChild.src;
// this will play and loop the audio with increased gain
var video = T("audio", {loop:true}).load(src, function(res) {
T("comp", {thresh:-48, knee:30, ratio:24, gain:18}, this).play();
});

HTML5 video for iPhone / iPad. How to detect connection speed?

I need to stream a video in Safari for iPhone/iPad with the best possible quality.
I created 2 video files: one in low-quality for slow 3G speed, one in hi-quality for WiFi broadband streaming. I noticed that some apps (YouTube for example) are able to detect if the mobile device is running by 3G or WiFi, and so select a small sized video rather than an hi-quality video.
Now that is my DOM / Javascript code, the $v value is replaced by PHP and contains the video filename:
<video id="thevideo" src="streaming/video_<?=$v ?>.m4v" width="600" height="360" width="640" height="360" preload="preload" controls="controls" autoplay="autoplay">
flowplayer/video<?=$v ?>.m4v
</video>
<script type="text/javascript">
var myvideo = document.getElementById("thevideo");
myvideo.load();
myvideo.play();
</script>
Can I write something in Javascript / Webkit that is able to detect the connection mode?
Thanks to all.
You will have to load some sort of document to test your connection speed.
an example -- http://alexle.net/archives/257
I am assuming this will be in your own application:
You could use Apple's Reachability to determine the connection type in your application before sending the UIWebView's request. You can modify the request's URL by adding a query:
//determine the connection type via Reachability
myURLString = [myURLString stringByAppendingString:[NSString stringWithFormat:#"?conntype=%#", *connTypeString]];
//then send the request for the page.
Then, parse the URL query in PHP to determine the video URL that should be used.
If not, you would need to test the connection speed via a third-party Javascript or PHP script.
Example: http://jan.moesen.nu/code/php/speedtest/index.php?numKB=512