Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added RTMP support. fixes #559 #605

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/tech.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ When adding additional Tech to a video player, make sure to add the supported te
techOrder: ["html5", "flash", "other supported tech"]
});

Flash Technology
==================
The flash playback tech is a part of the default `techOrder`. You may notice undesirable playback performance in browsers that are subject to using this playback tech, in particular when scrubbing and seeking within a video. These performance issues are a result of flash's progressive video playback.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actual docs, fantastic! Looks good to me. Looks like this is now the pull request to take in and delete the other two. I have a few small comments in here, but nothing major...

A nitpick, but I always see "flash" as "Flash".

Is it playback performance that's the problem with progressive video, or just "playback behavior"? I assume this scrubbing/seeking comment is about the fact that you can't seek into a progressive video as done currently. I was confused here for a second, wondering what the "performance" part of this was.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it might be fair to call it "behavior." Technically the browser is doing progressive playback too with HTML5, its just that its able to request content ranges so it appears to be more responsive when seeking.


Enabling Streaming Playback
--------------------------------
In order to force the flash tech to choose streaming playback, you need to provide a valid streaming source **before other valid flash video sources**. This is necessary because of the source selection algorithm, where playback tech chooses the first possible source object with a valid type. Valid streaming `type` values include `rtmp/mp4` and `rtmp/flv`. The streaming `src` value requires valid connection and stream strings, separated by an `&`. An example of supplying a streaming source through your HTML markup might look like:

<source src="rtmp://your.streaming.provider.net/cfx/st/&mp4:path/to/video.mp4" type="rtmp/mp4">
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
<source src="http://your.static.provider.net/path/to/video.webm" type="video/webm">

You may optionally use the last `/` as the separator between connection and stream strings, for example:

<source src="rtmp://your.streaming.provider.net/cfx/st/mp4:video.mp4" type="rtmp/mp4">

All four RTMP protocols are valid in the `src`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to list the four for those who don't know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made these suggested updates now on github.

On Sun, Aug 18, 2013 at 7:36 PM, Brian Deitte notifications@github.comwrote:

In docs/tech.md:

+==================
+The flash playback tech is a part of the default techOrder. You may notice undesirable playback performance in browsers that are subject to using this playback tech, in particular when scrubbing and seeking within a video. These performance issues are a result of flash's progressive video playback.
+
+Enabling Streaming Playback
+--------------------------------
+In order to force the flash tech to choose streaming playback, you need to provide a valid streaming source before other valid flash video sources. This is necessary because of the source selection algorithm, where playback tech chooses the first possible source object with a valid type. Valid streaming type values include rtmp/mp4 and rtmp/flv. The streaming src value requires valid connection and stream strings, separated by an &. An example of supplying a streaming source through your HTML markup might look like:
+

+You may optionally use the last / as the separator between connection and stream strings, for example:
+

+All four RTMP protocols are valid in the src.

It might be nice to list the four for those who don't know.


Reply to this email directly or view it on GitHubhttps://github.com//pull/605/files#r5833151
.


Youtube Technology
==================
To add a youtube source to your video tag, use the following source:
Expand Down
92 changes: 86 additions & 6 deletions src/js/media/flash.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ vjs.Flash = vjs.MediaTechController.extend({

// If source was supplied pass as a flash var.
if (source) {
flashVars['src'] = encodeURIComponent(vjs.getAbsoluteURL(source.src));
if (source.type && vjs.Flash.isStreamingType(source.type)) {
var parts = vjs.Flash.streamToParts(source.src);
flashVars['rtmpConnection'] = encodeURIComponent(parts.connection);
flashVars['rtmpStream'] = encodeURIComponent(parts.stream);
}
else {
flashVars['src'] = encodeURIComponent(vjs.getAbsoluteURL(source.src));
}
}

// Add placeholder to player div
Expand Down Expand Up @@ -224,10 +231,16 @@ vjs.Flash.prototype.pause = function(){
};

vjs.Flash.prototype.src = function(src){
// Make sure source URL is abosolute.
src = vjs.getAbsoluteURL(src);

this.el_.vjs_src(src);
if (vjs.Flash.isStreamingSrc(src)) {
src = vjs.Flash.streamToParts(src);
this.setRtmpConnection(src.connection);
this.setRtmpStream(src.stream);
}
else {
// Make sure source URL is abosolute.
src = vjs.getAbsoluteURL(src);
this.el_.vjs_src(src);
}

// Currently the SWF doesn't autoplay if you load a source later.
// e.g. Load player w/ no source, wait 2s, set src.
Expand All @@ -237,6 +250,20 @@ vjs.Flash.prototype.src = function(src){
}
};

vjs.Flash.prototype.currentSrc = function(){
var src = this.el_.vjs_getProperty("currentSrc");
// no src, check and see if RTMP
if (src == null) {
var connection = this.rtmpConnection(),
stream = this.rtmpStream();

if (connection && stream) {
src = vjs.Flash.streamFromParts(connection, stream);
}
}
return src;
};

vjs.Flash.prototype.load = function(){
this.el_.vjs_load();
};
Expand Down Expand Up @@ -301,7 +328,7 @@ vjs.Flash.isSupported = function(){
};

vjs.Flash.canPlaySource = function(srcObj){
if (srcObj.type in vjs.Flash.formats) { return 'maybe'; }
if (srcObj.type in vjs.Flash.formats || srcObj.type in vjs.Flash.streamingFormats) { return 'maybe'; }
};

vjs.Flash.formats = {
Expand All @@ -311,6 +338,11 @@ vjs.Flash.formats = {
'video/m4v': 'MP4'
};

vjs.Flash.streamingFormats = {
'rtmp/mp4': 'MP4',
'rtmp/flv': 'FLV'
};

vjs.Flash['onReady'] = function(currSwf){
var el = vjs.el(currSwf);

Expand Down Expand Up @@ -447,3 +479,51 @@ vjs.Flash.getEmbedCode = function(swf, flashVars, params, attributes){

return objTag + attrsString + '>' + paramsString + '</object>';
};

vjs.Flash.streamFromParts = function(connection, stream) {
return connection + "&" + stream;
};

vjs.Flash.streamToParts = function(src) {
var parts = {
connection: '',
stream: ''
};

if (! src) {
return parts;
}

// Look for the normal URL separator we expect, '&'.
// If found, we split the URL into two pieces around the
// first '&'.
var connEnd = src.indexOf('&');
var streamBegin;
if (connEnd !== -1) {
streamBegin = connEnd + 1;
}
else {
// If there's not a '&', we use the last '/' as the delimiter.
connEnd = streamBegin = src.lastIndexOf('/') + 1;
if (connEnd === 0) {
// really, there's not a '/'?
connEnd = streamBegin = src.length;
}
}
parts.connection = src.substring(0, connEnd);
parts.stream = src.substring(streamBegin, src.length);

return parts;
};

vjs.Flash.isStreamingType = function(srcType) {
return srcType in vjs.Flash.streamingFormats;
};

// RTMP has four variations, any string starting
// with one of these protocols should be valid
vjs.Flash.RTMP_RE = /^rtmp[set]?:\/\//i;

vjs.Flash.isStreamingSrc = function(src) {
return vjs.Flash.RTMP_RE.test(src);
};
Binary file modified src/swf/video-js.swf
Binary file not shown.
3 changes: 2 additions & 1 deletion test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
'test/unit/core.js',
'test/unit/media.html5.js',
'test/unit/controls.js',
'test/unit/plugins.js'
'test/unit/plugins.js',
'test/unit/flash.js'
];

var projectRoot = '../';
Expand Down
48 changes: 48 additions & 0 deletions test/unit/flash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module('Flash');

var streamToPartsAndBack = function(url) {
var parts = vjs.Flash.streamToParts(url);
return vjs.Flash.streamFromParts(parts.connection, parts.stream);
};

test('test using both streamToParts and streamFromParts', function() {
ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/isthis'));
ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/&isthis'));
ok('rtmp://myurl.com/isthis/&andthis' === streamToPartsAndBack('rtmp://myurl.com/isthis/andthis'));
});

test('test streamToParts', function() {
var parts = vjs.Flash.streamToParts('http://myurl.com/streaming&/is/fun');
ok(parts.connection === 'http://myurl.com/streaming');
ok(parts.stream === '/is/fun');

parts = vjs.Flash.streamToParts('http://myurl.com/&streaming&/is/fun');
ok(parts.connection === 'http://myurl.com/');
ok(parts.stream === 'streaming&/is/fun');

parts = vjs.Flash.streamToParts('http://myurl.com/streaming/is/fun');
ok(parts.connection === 'http://myurl.com/streaming/is/');
ok(parts.stream === 'fun');

parts = vjs.Flash.streamToParts('whatisgoingonhere');
ok(parts.connection === 'whatisgoingonhere');
ok(parts.stream === '');

parts = vjs.Flash.streamToParts();
ok(parts.connection === '');
ok(parts.stream === '');
});

test('test isStreamingSrc', function() {
var isStreamingSrc = vjs.Flash.isStreamingSrc;
ok(isStreamingSrc('rtmp://streaming.is/fun'));
ok(isStreamingSrc('rtmps://streaming.is/fun'));
ok(isStreamingSrc('rtmpe://streaming.is/fun'));
ok(isStreamingSrc('rtmpt://streaming.is/fun'));
// test invalid protocols
ok(!isStreamingSrc('rtmp:streaming.is/fun'));
ok(!isStreamingSrc('rtmpz://streaming.is/fun'));
ok(!isStreamingSrc('http://streaming.is/fun'));
ok(!isStreamingSrc('https://streaming.is/fun'));
ok(!isStreamingSrc('file://streaming.is/fun'));
});