Looking first for links to good documentation that correctly explains pseudostreaming, byte range requests and mp4 fragmenting. Note, I will be using only the mp4 container (h264 codec) and HTML5 video (no flash).
My understanding of pseudostreaming is that the client can send off a start parameter that the server "seeks" to in it's response. MOOV data must be upfront and it implicitly implies that buffering of the original source stops in favor of the new response starting at the "start"/seek position. How is the client forced to make pseudo calls? Does the MP4 have to formatted in a special way?
Byte range requests are different send rather than just a start parameter a range is sent. Sounds more like progressive downloading. How would "seeking" work? Does it with byte range? Can the segment size be pre-determined with movie box information?
How does MP4 fragmentation fit in? Looking like a construct originally designed by microsoft for silverlight. But is it applicable to other browser html5 video implementations?
Finding it difficult to sort out information on the web. Looking to both live feed and take historical segments of h264 files produced from rtp camera streams. Got a bunch of files time-ordered in a MongoDB. Created my own h264 decoder in JavaScript and can construct mpeg-dash boxes on the fly off a range query. Using Chrome's support for MSE to append segments. Works great but not a universal solution. Want to fall back on other techniques other than flash but with the html5 video.
Related
The big picture is that I want to live upload recorded audio from the browser directly to google drive.
This is a pet project so I am happy to play with experimental web technologies.
I currently have the browser fetching a feed from the microphone using MediaDevices.getUserMedia() and encoding it to mp3 in a WebWorker. The encoder returns an rxjs.Observable<Int16Array> that will produce chunks of the encoded file on subscribe.
I would like to use a resumable upload to upload the file, preferably in the "single request" style. The challenge is in uploading the file as it is produced by the encoder.
I appreciate that I could probably achieve a similar result by using their "multiple chunks" style and collecting the results of the encoder into Blobs and sending them on an interval. My problem with this is that the more "live" the upload is (smaller chunks) the more POST requests I will be making.
XMLHttpRequest.send() does specify that I can provide a ReadableStream as the body. BUT it appears that this experimental tech does not yet support byte streams
I am developing an iOS app that synchronises with GoPro cameras.
One of the feature requires downloading MP4 from the GoPro (potentially huge).
I basically have a url like: http://10.9.9.5/whatever/video.mp4.
However, I only need parts of the video, let's say between 1:00 and 1:05.
I am thinking on downloading just parts of the MP4, using HTTP "Range" header. I believe that it's possible and I will get a bunch of bytes.
However, is it a valid file? Will I be able to create a MP4 ? Do I need the MP4 header with meta information? Do any of you faced this kind of challenge?
I am using Objective C but I believe that this is a general question.
The MP4 file is a container for video that is structured around something called boxes. Probably you'll have h.264 video in that MP4 file, knowing that, you'll need to know the structure of the file you are trying to chunk.
Depending on the way it is encoded you'll have to look for a box with metadata that'll allow you to search for the correct part of the file either at the beginning or at the end, but you'll have to reconstruct a valid MP4 with the data you get from the original file.
You can see a reference of the file format here http://xhelmboyx.tripod.com/formats/mp4-layout.txt.
What is required to use SMIL file to utilize adaptive streaming in a videojs player. I have created the SMIL file in my wowza application and it is creating my 4 separate streams and making them available. However I cannot get my webpage, that uses videojs, to correctly play the SMIL file. Hints on that coding or where to go to find the correct documentation would be greatly appreciated.
There aren't many implementations of SMIL players. I'm sure I've seen wowza URLs that suggest it will output the SMIL as other formats, something like whatever.smil/manifest.m3u8. That's HLS which could be played on mobile and Safari natively and with videojs-contrib-hls elsewhere.
I know the question is old, but I've been struggling with this recently, so I want to share my experience in case anyone is interested. My scenario is very similar: want to deliver adaptive bitrate streaming from Wowza to clients using videojs.
There is a master link that explains how to setup and run Wowza Transcoder for live streaming, and how to set up your Adaptive Bitrate Streams using an SMIL file. Following the video in there you can achieve to have a stream that uses ABS, but the SMIL file is attached to the stream name, so it is not a solution if you have streams that come to Wowza from another Media Server origin and that need to be transcoded before being served to the clients. In the article there are a few key things mentioned (like the Stream Name Groups), but somehow things doesn't seem pretty clear, at least to me. So here is some clarification from what I understood from all articles I read and what I did to achieve ABS:
You can achieve ABS in Wowza either with SMIL files or with Stream Name Groups (NGRP). NGRP refres to a block of streams that is defined in the Transcoder template that can be played back using multi-bitrate streaming (dynamically) (<- this is what I used). And SMIL files are used to create a "static" list of streams for multi-bitrate VOD streaming. If you are using Wowza Origin-Edge Delivery you'll need the .smil file, because NGRP do not get forwarded to the edge. (Source for all this information: here).
In case you need the SMIL file, you probably need to generate a new one for every stream, and probably you want to do that in an automated way, so best way would be through an HTTP request (in the link above it is explained how to achieve this).
In case you can live with NGRP, things are a bit easier:
You need to enable Wowza Transcoder (this is pretty easy and steps are in the video I mention above).
You should create your own Transcoder Template with the different stream presets you want to deliver, as an example you can check the default ones that are already there. The more presets you add, the more work Wowza will need to do whenever a stream comes, since it will need to generate a new stream for every preset that you have defined.
Now is when we generate the NGRPs. In your Transcoder Template, you can generate as many NGRPs as you want (to clarify: these are like groups of streams, that you will be able to set in your clients video player. Each NGRP contains the streams that the video will be able to use when doing the adaptive bitrate streaming). For instance, these are the default NGRPs:
If you play the ngrp "_mobile" in the clients video player, the ABS algorithm in the player will be able to adapt itself to play either the 240p or the 160p streams based on the client capabilities.
So imagine you have these two NGRP. In order to play them in videoJS, you will need to set the source to:
http://[wowza-ip-address]:1935/<name-of-your-application>/ngrp:myStream_all/playlist.m3u8
or
http://[wowza-ip-address]:1935/<name-of-your-application>/ngrp:myStream_mobile/playlist.m3u8
... based on how many options you want to provide to the client player to use for the ABS. (For instance: if your targets are old mobile devices, you probably just want to offer a couple of low bitrate streams).
(This would be in case you're delivering an HLS stream. If other format, the extension would change, for instance if you are delivering a DASH stream you would have "/manifest.mpd" instead of "playlist.m3u8").
That is all, there is also a very helpful link in video.js documentation explaining how it does the bitrate switching: here.
I hope it helps someone! At least clarifying things! :)
While looking for video streaming server with Adaptive Bit Rate using http, I came across some proprietary servers/implementation namely Adobe dynamic streaming for Flash, Apple HTTP adaptive streaming and a similar one from microsoft.
What I am looking for is Apache webserver ABR streaming, I found out that MPEG DASH is the standard for this, and looks like apache supports it. But I am not able to get a start to it.
Can someone point me to an example or steps to achieve this?
Also, I understand that such a streaming requires a bunch of video files acting as segments at different bit rates of a video file that needs to be streamed and some metadata file.
I am not able to understand how I can provide this to apache to make it stream to the client(browser).
Appreciate help or directions on this.
Thanks.
Using MPEG-DASH, streaming becomes very simple. The video is stored at different quality levels (in terms of bitrate, resolution, etc.) on any HTTP server, each divided in segments of a few seconds length. The (intelligent) client application requests the segment for a specific time and quality (dependent on the current network capacity) via standard HTTP GET requests. So you can use your "standard" apache or any other webserver.
To get started I suggest to get some DASH content, either from DASHIF, or generate content on your own the easy way, using a transcoding platforms, like bitcodin.
I have created one sample application for demonstrating a working of HTTP live streaming.
What I have done is, I have one library that takes input as video file (avi, mpeg, mov, .ts) and generating segments (.ts) and playlist (.m3u8) files for the given video file. I am storing playlist (as string) in a linked list, as an when i am getting playlist data from the library.
I have written one basic web server which will server the user requested segment and playlist files. I am requesting playlist.m3u8 file from the iPhone safari browser and it is launching the QuickTime player where it is requesting the segment.ts files listed in the received playlist files. after playing every segments (listed in current playlist) it again requests for the playlist, where i am responding with the next playlist file which contains the next set of segment.ts files listed in it.
Is this what we call HTTP live streaming?
Is there anything else, other that this i need to do for implementing HTTP live streaming?
Thanks.
Not much more. If you are taking input streams of media, encoding them, encapsulating in a format suitable for delivery and preparing the encapsulated media for distribution by placing it in such a way that they can be requested from the HTTP server, you are done. The idea behind the live streaming is that it leverages existing Internet architecture that is already optimized for serving HTTP requests for reasonably sized resources.
HTTP streaming renders many existing CDN solutions obsolete with their custom streaming protocols, custom routing and custom content caching.
You can also use media stream validator command line application for mac os x for validating streams generated by the HTTP Web server.
More or less but there's also adaptive bit-rate streaming to take care of if you want your server to push files to iOS devices. Which means your scope expands from having a single "index.m3u8" file that tracks all the TS files to a master index that then tracks the index files for each bitrate you'd want to support in your application which then individually track the TS files encoded at the respective bit-rates.
It's a good amount of work, but mostly routine/repetitive once you've got the hang of the basics.
For more on streaming, your bible, from the iOS standpoint, should ALWAYS be TN2224. Adhering closely to the specs in the Technote, is your best chance of getting through the App Store approval process vis-a-vis streaming.
Some people don't bother (building a streaming app over the past couple of months and looked at the HTTP logs of a whole bunch of video apps that don't quite seem to stick by the rules) - sometimes Apple notices, sometimes they don't, and sometimes the player is just too big for Apple to interfere.
So it's not very different there from every other aspect of the functionality of your app that undergoes Apple's scrutiny. It's just that there are ways you can be sure you're on the right track.
And of course, from a purely technical standpoint, as #psp1 mentioned the mediastreamvalidator tool can help you figure out if your streams are - at their very core, even if not in terms of their overall abilities - compatible with what's expected of HLS implementations.
Note: You can either roll with your own encoding solution (with ffmpeg, the plus being you have more control, the minus being it takes time to configure and get working just RIGHT. Plus once you start talking even the least amount of scale, you run into a whole host of other problems. And once you're done with all the technical hard-work, you'd find that was easy. Now you'd have to actually figure out which license you need to get for having a fancy H.264 encoder with you and jump through all the legal/procedural hoops to get one).
The easier solution for a developer without a legal/accounting team that could fill a football field, IMO, it's easier to go third-party with sites like Encoding.com, Zencoder etc who provide their encoding services a-la-carte or with a monthly fee. The plus is that they've taken care of all the licensing BS and are just providing you a simple "pay to use" service, which could also be extremely useful when you're building a project for a client. The minus is that you're now DEPENDENT on Zencoder/Encoding, the flip-side of which you'd know when your encoding jobs fail for a whole day because their servers are down, or even otherwise, when the API doesn't quite act as you expect or has been documented!
But anyhow that's about all the factors you got to Grok before pushing a HLS server into production!