mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
add fullscreen event and rescale
This commit is contained in:
parent
02f46d6fcc
commit
065cbbe4aa
5 changed files with 497 additions and 237 deletions
BIN
trunk/research/players/img/tooltip.png
Normal file
BIN
trunk/research/players/img/tooltip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 783 B |
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* update the navigator, add same query string.
|
||||||
|
*/
|
||||||
function update_nav() {
|
function update_nav() {
|
||||||
$("#nav_srs_player").attr("href", "srs_player.html" + window.location.search);
|
$("#nav_srs_player").attr("href", "srs_player.html" + window.location.search);
|
||||||
$("#nav_srs_publisher").attr("href", "srs_publisher.html" + window.location.search);
|
$("#nav_srs_publisher").attr("href", "srs_publisher.html" + window.location.search);
|
||||||
|
@ -7,6 +10,9 @@ function update_nav() {
|
||||||
$("#nav_vlc").attr("href", "vlc.html" + window.location.search);
|
$("#nav_vlc").attr("href", "vlc.html" + window.location.search);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse the query string to object.
|
||||||
|
*/
|
||||||
function parse_query_string(){
|
function parse_query_string(){
|
||||||
var query_string = String(window.location.search).replace(" ", "").split("?")[1];
|
var query_string = String(window.location.search).replace(" ", "").split("?")[1];
|
||||||
if(query_string == undefined){
|
if(query_string == undefined){
|
||||||
|
@ -60,6 +66,11 @@ function build_default_hls_url() {
|
||||||
return "http://" + vhost + ":" + port + "/" + app + "/" + stream + ".m3u8";
|
return "http://" + vhost + ":" + port + "/" + app + "/" + stream + ".m3u8";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize the page.
|
||||||
|
* @param rtmp_url the rtmp stream url to play
|
||||||
|
* @param hls_url the hls stream url to play
|
||||||
|
*/
|
||||||
function srs_init(rtmp_url, hls_url) {
|
function srs_init(rtmp_url, hls_url) {
|
||||||
update_nav();
|
update_nav();
|
||||||
|
|
||||||
|
@ -70,3 +81,146 @@ function srs_init(rtmp_url, hls_url) {
|
||||||
$(hls_url).val(build_default_hls_url());
|
$(hls_url).val(build_default_hls_url());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* the SrsPlayer object.
|
||||||
|
*/
|
||||||
|
function SrsPlayer(container, stream_url, width, height, buffer_time) {
|
||||||
|
if (!SrsPlayer.__id) {
|
||||||
|
SrsPlayer.__id = 100;
|
||||||
|
}
|
||||||
|
if (!SrsPlayer.__players) {
|
||||||
|
SrsPlayer.__players = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsPlayer.__players.push(this);
|
||||||
|
|
||||||
|
this.container = container;
|
||||||
|
this.stream_url = stream_url;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.buffer_time = buffer_time;
|
||||||
|
this.id = SrsPlayer.__id++;
|
||||||
|
this.callbackObj = null;
|
||||||
|
|
||||||
|
// callback set the following values.
|
||||||
|
this.meatadata = {}; // for on_player_metadata
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* user can set some callback, then start the player.
|
||||||
|
* callbacks:
|
||||||
|
* on_player_ready():int, when srs player ready, user can play.
|
||||||
|
* on_player_metadata(metadata:Object):int, when srs player get metadata.
|
||||||
|
*/
|
||||||
|
SrsPlayer.prototype.start = function() {
|
||||||
|
// embed the flash.
|
||||||
|
var flashvars = {};
|
||||||
|
flashvars.id = this.id;
|
||||||
|
flashvars.on_player_ready = "__srs_on_player_ready";
|
||||||
|
flashvars.on_player_metadata = "__srs_on_player_metadata";
|
||||||
|
|
||||||
|
var params = {};
|
||||||
|
params.wmode = "opaque";
|
||||||
|
params.allowFullScreen = "true";
|
||||||
|
params.allowScriptAccess = "always";
|
||||||
|
|
||||||
|
var attributes = {};
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
swfobject.embedSWF(
|
||||||
|
"srs_player/release/srs_player.swf", this.container,
|
||||||
|
this.width, this.height,
|
||||||
|
"11.1", "js/AdobeFlashPlayerInstall.swf",
|
||||||
|
flashvars, params, attributes,
|
||||||
|
function(callbackObj){
|
||||||
|
self.callbackObj = callbackObj;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
SrsPlayer.prototype.play = function() {
|
||||||
|
return this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time);
|
||||||
|
}
|
||||||
|
SrsPlayer.prototype.stop = function() {
|
||||||
|
for (var i = 0; i < SrsPlayer.__players.length; i++) {
|
||||||
|
var player = SrsPlayer.__players[i];
|
||||||
|
|
||||||
|
if (player.id != this.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsPlayer.__players.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this.callbackObj.ref.__stop();
|
||||||
|
}
|
||||||
|
SrsPlayer.prototype.pause = function() {
|
||||||
|
return this.callbackObj.ref.__pause();
|
||||||
|
}
|
||||||
|
SrsPlayer.prototype.resume = function() {
|
||||||
|
return this.callbackObj.ref.__resume();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* to set the DAR, for example, DAR=16:9
|
||||||
|
* @param num, for example, 9.
|
||||||
|
* use metadata height if 0.
|
||||||
|
* use user specified height if -1.
|
||||||
|
* @param den, for example, 16.
|
||||||
|
* use metadata width if 0.
|
||||||
|
* use user specified width if -1.
|
||||||
|
*/
|
||||||
|
SrsPlayer.prototype.dar = function(num, den) {
|
||||||
|
return this.callbackObj.ref.__dar(num, den);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* set the fullscreen size data.
|
||||||
|
* @refer the refer fullscreen mode. it can be:
|
||||||
|
* video: use video orignal size.
|
||||||
|
* screen: use screen size to rescale video.
|
||||||
|
* @param percent, the rescale percent, where
|
||||||
|
* 100 means 100%.
|
||||||
|
*/
|
||||||
|
SrsPlayer.prototype.set_fs = function(refer, percent) {
|
||||||
|
return this.callbackObj.ref.__set_fs(refer, percent);
|
||||||
|
}
|
||||||
|
SrsPlayer.prototype.on_player_ready = function() {
|
||||||
|
return this.play();
|
||||||
|
}
|
||||||
|
SrsPlayer.prototype.on_player_metadata = function(metadata) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
function __srs_on_player_ready(id) {
|
||||||
|
for (var i = 0; i < SrsPlayer.__players.length; i++) {
|
||||||
|
var player = SrsPlayer.__players[i];
|
||||||
|
|
||||||
|
if (player.id != id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return player.on_player_ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("player not found. id=" + id);
|
||||||
|
}
|
||||||
|
function __srs_on_player_metadata(id, metadata) {
|
||||||
|
for (var i = 0; i < SrsPlayer.__players.length; i++) {
|
||||||
|
var player = SrsPlayer.__players[i];
|
||||||
|
|
||||||
|
if (player.id != id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// user may override the on_player_metadata,
|
||||||
|
// so set the data before invoke it.
|
||||||
|
player.metadata = metadata;
|
||||||
|
|
||||||
|
return player.on_player_metadata(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("player not found. id=" + id);
|
||||||
|
}
|
||||||
|
|
|
@ -14,13 +14,30 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var active_dar = null;
|
var srs_player = null;
|
||||||
function select_dar(dar_id) {
|
|
||||||
if (active_dar) {
|
var __active_dar = null;
|
||||||
active_dar.removeClass("active");
|
function select_dar(dar_id, num, den) {
|
||||||
|
srs_player.dar(num, den);
|
||||||
|
|
||||||
|
if (__active_dar) {
|
||||||
|
__active_dar.removeClass("active");
|
||||||
}
|
}
|
||||||
active_dar = $(dar_id).parent();
|
|
||||||
active_dar.addClass("active");
|
__active_dar = $(dar_id).parent();
|
||||||
|
__active_dar.addClass("active");
|
||||||
|
}
|
||||||
|
|
||||||
|
var __active_size = null;
|
||||||
|
function select_fs_size(size_id, refer, percent) {
|
||||||
|
srs_player.set_fs(refer, percent);
|
||||||
|
|
||||||
|
if (__active_size) {
|
||||||
|
__active_size.removeClass("active");
|
||||||
|
}
|
||||||
|
|
||||||
|
__active_size = $(size_id).parent();
|
||||||
|
__active_size.addClass("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
@ -29,9 +46,15 @@
|
||||||
// url set to: rtmp://demo:1935/live/livestream
|
// url set to: rtmp://demo:1935/live/livestream
|
||||||
srs_init($("#txt_url"));
|
srs_init($("#txt_url"));
|
||||||
|
|
||||||
var srs_player = null;
|
$("#fs_tips").tooltip({
|
||||||
|
title: "点击视频进入或退出全屏"
|
||||||
|
});
|
||||||
|
|
||||||
$("#main_modal").on("show", function(){
|
$("#main_modal").on("show", function(){
|
||||||
|
if (srs_player) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$("#div_container").remove();
|
$("#div_container").remove();
|
||||||
|
|
||||||
var obj = $("<div/>");
|
var obj = $("<div/>");
|
||||||
|
@ -51,16 +74,22 @@
|
||||||
}
|
}
|
||||||
srs_player.on_player_metadata = function(metadata) {
|
srs_player.on_player_metadata = function(metadata) {
|
||||||
$("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
|
$("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
|
||||||
srs_player.dar(0, 0);
|
select_dar("#btn_dar_original", 0, 0);
|
||||||
select_dar("#btn_dar_original");
|
select_fs_size("#btn_fs_size_screen_100", "screen", 100);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
srs_player.start();
|
srs_player.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#main_modal").on("hide", function(){
|
$("#main_modal").on("hide", function(){
|
||||||
srs_player.stop();
|
if ($("#main_modal").is(":visible")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srs_player) {
|
||||||
|
srs_player.stop();
|
||||||
|
srs_player = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#btn_play").click(function(){
|
$("#btn_play").click(function(){
|
||||||
|
@ -68,177 +97,54 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#btn_pause").click(function(){
|
$("#btn_pause").click(function(){
|
||||||
if ($("#btn_pause").text() == "暂停") {
|
if ($("#btn_pause").text() == "暂停播放") {
|
||||||
$("#btn_pause").text("继续");
|
$("#btn_pause").text("继续播放");
|
||||||
srs_player.pause();
|
srs_player.pause();
|
||||||
} else {
|
} else {
|
||||||
$("#btn_pause").text("暂停");
|
$("#btn_pause").text("暂停播放");
|
||||||
srs_player.resume();
|
srs_player.resume();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#btn_dar_original").click(function(){
|
if (true) {
|
||||||
srs_player.dar(0, 0);
|
$("#btn_dar_original").click(function(){
|
||||||
select_dar("#btn_dar_original");
|
select_dar("#btn_dar_original", 0, 0);
|
||||||
});
|
});
|
||||||
$("#btn_dar_21_9").click(function(){
|
$("#btn_dar_21_9").click(function(){
|
||||||
srs_player.dar(9, 21);
|
select_dar("#btn_dar_21_9", 9, 21);
|
||||||
select_dar("#btn_dar_21_9");
|
});
|
||||||
});
|
$("#btn_dar_16_9").click(function(){
|
||||||
$("#btn_dar_16_9").click(function(){
|
select_dar("#btn_dar_16_9", 9, 16);
|
||||||
srs_player.dar(9, 16);
|
});
|
||||||
select_dar("#btn_dar_16_9");
|
$("#btn_dar_4_3").click(function(){
|
||||||
});
|
select_dar("#btn_dar_4_3", 3, 4);
|
||||||
$("#btn_dar_4_3").click(function(){
|
});
|
||||||
srs_player.dar(3, 4);
|
$("#btn_dar_fill").click(function(){
|
||||||
select_dar("#btn_dar_4_3");
|
select_dar("#btn_dar_fill", -1, -1);
|
||||||
});
|
});
|
||||||
$("#btn_dar_fill").click(function(){
|
}
|
||||||
srs_player.dar(-1, -1);
|
|
||||||
select_dar("#btn_dar_fill");
|
if (true) {
|
||||||
});
|
$("#btn_fs_size_video_100").click(function(){
|
||||||
|
select_fs_size("#btn_fs_size_video_100", "video", 100);
|
||||||
|
});
|
||||||
|
$("#btn_fs_size_video_75").click(function(){
|
||||||
|
select_fs_size("#btn_fs_size_video_75", "video", 75);
|
||||||
|
});
|
||||||
|
$("#btn_fs_size_video_50").click(function(){
|
||||||
|
select_fs_size("#btn_fs_size_video_50", "video", 50);
|
||||||
|
});
|
||||||
|
$("#btn_fs_size_screen_100").click(function(){
|
||||||
|
select_fs_size("#btn_fs_size_screen_100", "screen", 100);
|
||||||
|
});
|
||||||
|
$("#btn_fs_size_screen_75").click(function(){
|
||||||
|
select_fs_size("#btn_fs_size_screen_75", "screen", 75);
|
||||||
|
});
|
||||||
|
$("#btn_fs_size_screen_50").click(function(){
|
||||||
|
select_fs_size("#btn_fs_size_screen_50", "screen", 50);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
* the SrsPlayer object.
|
|
||||||
*/
|
|
||||||
function SrsPlayer(container, stream_url, width, height, buffer_time) {
|
|
||||||
if (!SrsPlayer.__id) {
|
|
||||||
SrsPlayer.__id = 100;
|
|
||||||
}
|
|
||||||
if (!SrsPlayer.__players) {
|
|
||||||
SrsPlayer.__players = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsPlayer.__players.push(this);
|
|
||||||
|
|
||||||
this.container = container;
|
|
||||||
this.stream_url = stream_url;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
this.buffer_time = buffer_time;
|
|
||||||
this.id = SrsPlayer.__id++;
|
|
||||||
this.callbackObj = null;
|
|
||||||
|
|
||||||
// callback set the following values.
|
|
||||||
this.meatadata = {}; // for on_player_metadata
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* user can set some callback, then start the player.
|
|
||||||
* callbacks:
|
|
||||||
* on_player_ready():int, when srs player ready, user can play.
|
|
||||||
* on_player_metadata(metadata:Object):int, when srs player get metadata.
|
|
||||||
*/
|
|
||||||
SrsPlayer.prototype.start = function() {
|
|
||||||
// embed the flash.
|
|
||||||
var flashvars = {};
|
|
||||||
flashvars.id = this.id;
|
|
||||||
flashvars.on_player_ready = "__srs_on_player_ready";
|
|
||||||
flashvars.on_player_metadata = "__srs_on_player_metadata";
|
|
||||||
|
|
||||||
var params = {};
|
|
||||||
params.wmode = "opaque";
|
|
||||||
params.allowFullScreen = true;
|
|
||||||
params.allowScriptAccess = "always";
|
|
||||||
|
|
||||||
var attributes = {};
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
swfobject.embedSWF(
|
|
||||||
"srs_player/release/srs_player.swf", this.container,
|
|
||||||
this.width, this.height,
|
|
||||||
"11.1", "js/AdobeFlashPlayerInstall.swf",
|
|
||||||
flashvars, params, attributes,
|
|
||||||
function(callbackObj){
|
|
||||||
self.callbackObj = callbackObj;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
SrsPlayer.prototype.play = function() {
|
|
||||||
return this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time);
|
|
||||||
}
|
|
||||||
SrsPlayer.prototype.stop = function() {
|
|
||||||
for (var i = 0; i < SrsPlayer.__players.length; i++) {
|
|
||||||
var player = SrsPlayer.__players[i];
|
|
||||||
|
|
||||||
if (player.id != this.id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsPlayer.__players.splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return this.callbackObj.ref.__stop();
|
|
||||||
}
|
|
||||||
SrsPlayer.prototype.pause = function() {
|
|
||||||
return this.callbackObj.ref.__pause();
|
|
||||||
}
|
|
||||||
SrsPlayer.prototype.resume = function() {
|
|
||||||
return this.callbackObj.ref.__resume();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* to set the DAR, for example, DAR=16:9
|
|
||||||
* @param num, for example, 9.
|
|
||||||
* use metadata height if 0.
|
|
||||||
* use user specified height if -1.
|
|
||||||
* @param den, for example, 16.
|
|
||||||
* use metadata width if 0.
|
|
||||||
* use user specified width if -1.
|
|
||||||
*/
|
|
||||||
SrsPlayer.prototype.dar = function(num, den) {
|
|
||||||
if (num == 0 && this.metadata) {
|
|
||||||
num = this.metadata.height;
|
|
||||||
} else if (num == -1) {
|
|
||||||
num = this.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (den == 0 && this.metadata) {
|
|
||||||
den = this.metadata.width;
|
|
||||||
} else if (den == -1) {
|
|
||||||
den = this.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.callbackObj.ref.__dar(num, den);
|
|
||||||
}
|
|
||||||
SrsPlayer.prototype.on_player_ready = function() {
|
|
||||||
return this.play();
|
|
||||||
}
|
|
||||||
SrsPlayer.prototype.on_player_metadata = function(metadata) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
function __srs_on_player_ready(id) {
|
|
||||||
for (var i = 0; i < SrsPlayer.__players.length; i++) {
|
|
||||||
var player = SrsPlayer.__players[i];
|
|
||||||
|
|
||||||
if (player.id != id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return player.on_player_ready();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("player not found. id=" + id);
|
|
||||||
}
|
|
||||||
function __srs_on_player_metadata(id, metadata) {
|
|
||||||
for (var i = 0; i < SrsPlayer.__players.length; i++) {
|
|
||||||
var player = SrsPlayer.__players[i];
|
|
||||||
|
|
||||||
if (player.id != id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// user may override the on_player_metadata,
|
|
||||||
// so set the data before invoke it.
|
|
||||||
player.metadata = metadata;
|
|
||||||
|
|
||||||
return player.on_player_metadata(metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("player not found. id=" + id);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -278,17 +184,37 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="btn-group dropup">
|
<div class="btn-group dropup">
|
||||||
<button class="btn dropdown-toggle" data-toggle="dropdown">宽高比 <span class="caret"></span></button>
|
<button class="btn dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<a id="fs_tips" href="#" data-toggle="tooltip" data-placement="top" title="">
|
||||||
|
<img src="img/tooltip.png"/>
|
||||||
|
</a>
|
||||||
|
全屏大小<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a id="btn_fs_size_screen_100" href="#">屏幕大小(100%)</a></li>
|
||||||
|
<li><a id="btn_fs_size_screen_75" href="#">屏幕大小(75%)</a></li>
|
||||||
|
<li><a id="btn_fs_size_screen_50" href="#">屏幕大小(50%)</a></li>
|
||||||
|
<li><a id="btn_fs_size_video_100" href="#">视频大小(100%)</a></li>
|
||||||
|
<li><a id="btn_fs_size_video_75" href="#">视频大小(75%)</a></li>
|
||||||
|
<li><a id="btn_fs_size_video_50" href="#">视频大小(50%)</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group dropup">
|
||||||
|
<button class="btn dropdown-toggle" data-toggle="dropdown">显示比例<span class="caret"></span></button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a id="btn_dar_original" href="#">视频原始比例</a></li>
|
<li><a id="btn_dar_original" href="#">视频原始比例</a></li>
|
||||||
<li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li>
|
<li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li>
|
||||||
<li><a id="btn_dar_16_9" href="#">宽屏电影(16:9)</a></li>
|
<li><a id="btn_dar_16_9" href="#">宽屏电影(16:9)</a></li>
|
||||||
<li><a id="btn_dar_4_3" href="#">窄屏(4:3)</a></li>
|
<li><a id="btn_dar_4_3" href="#">窄屏(4:3)</a></li>
|
||||||
<li><a id="btn_dar_fill" href="#">填充</a></li>
|
<li><a id="btn_dar_fill" href="#">填充(容器比例)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<button id="btn_pause" class="btn">暂停</button>
|
<div class="btn-group dropup">
|
||||||
<button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button>
|
<button id="btn_pause" class="btn">暂停播放</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group dropup">
|
||||||
|
<button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
Binary file not shown.
|
@ -2,13 +2,17 @@ package
|
||||||
{
|
{
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
import flash.display.StageAlign;
|
import flash.display.StageAlign;
|
||||||
|
import flash.display.StageDisplayState;
|
||||||
import flash.display.StageScaleMode;
|
import flash.display.StageScaleMode;
|
||||||
import flash.events.Event;
|
import flash.events.Event;
|
||||||
|
import flash.events.FullScreenEvent;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
import flash.events.NetStatusEvent;
|
import flash.events.NetStatusEvent;
|
||||||
import flash.external.ExternalInterface;
|
import flash.external.ExternalInterface;
|
||||||
import flash.media.Video;
|
import flash.media.Video;
|
||||||
import flash.net.NetConnection;
|
import flash.net.NetConnection;
|
||||||
import flash.net.NetStream;
|
import flash.net.NetStream;
|
||||||
|
import flash.system.Security;
|
||||||
import flash.ui.ContextMenu;
|
import flash.ui.ContextMenu;
|
||||||
import flash.ui.ContextMenuItem;
|
import flash.ui.ContextMenuItem;
|
||||||
import flash.utils.setTimeout;
|
import flash.utils.setTimeout;
|
||||||
|
@ -23,18 +27,29 @@ package
|
||||||
|
|
||||||
// play param url.
|
// play param url.
|
||||||
private var url:String = null;
|
private var url:String = null;
|
||||||
// play param, user set width
|
// play param, user set width and height
|
||||||
private var w:int = 0;
|
private var w:int = 0;
|
||||||
// play param, user set height.
|
|
||||||
private var h:int = 0;
|
private var h:int = 0;
|
||||||
|
// user set dar den:num
|
||||||
|
private var dar_num:int = 0;
|
||||||
|
private var dar_den:int = 0;
|
||||||
|
// user set fs(fullscreen) refer and percent.
|
||||||
|
private var fs_refer:String = null;
|
||||||
|
private var fs_percent:int = 0;
|
||||||
|
|
||||||
private var conn:NetConnection = null;
|
private var conn:NetConnection = null;
|
||||||
private var stream:NetStream = null;
|
private var stream:NetStream = null;
|
||||||
private var video:Video = null;
|
private var video:Video = null;
|
||||||
private var metadata:Object = {};
|
private var metadata:Object = {};
|
||||||
|
|
||||||
|
// flash donot allow js to set to fullscreen,
|
||||||
|
// only allow user click to enter fullscreen.
|
||||||
|
private var fs_mask:Sprite = new Sprite();
|
||||||
|
|
||||||
public function srs_player()
|
public function srs_player()
|
||||||
{
|
{
|
||||||
|
flash.system.Security.allowDomain("*");
|
||||||
|
|
||||||
if (!this.stage) {
|
if (!this.stage) {
|
||||||
this.addEventListener(Event.ADDED_TO_STAGE, this.onAddToStage);
|
this.addEventListener(Event.ADDED_TO_STAGE, this.onAddToStage);
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,6 +61,12 @@ package
|
||||||
this.stage.align = StageAlign.TOP_LEFT;
|
this.stage.align = StageAlign.TOP_LEFT;
|
||||||
this.stage.scaleMode = StageScaleMode.NO_SCALE;
|
this.stage.scaleMode = StageScaleMode.NO_SCALE;
|
||||||
|
|
||||||
|
this.stage.addEventListener(FullScreenEvent.FULL_SCREEN, this.on_stage_fullscreen);
|
||||||
|
|
||||||
|
this.addChild(this.fs_mask);
|
||||||
|
this.fs_mask.buttonMode = true;
|
||||||
|
this.fs_mask.addEventListener(MouseEvent.CLICK, on_user_click_video);
|
||||||
|
|
||||||
this.contextMenu = new ContextMenu();
|
this.contextMenu = new ContextMenu();
|
||||||
this.contextMenu.hideBuiltInItems();
|
this.contextMenu.hideBuiltInItems();
|
||||||
|
|
||||||
|
@ -62,13 +83,21 @@ package
|
||||||
this.on_player_ready = flashvars.on_player_ready;
|
this.on_player_ready = flashvars.on_player_ready;
|
||||||
this.on_player_metadata = flashvars.on_player_metadata;
|
this.on_player_metadata = flashvars.on_player_metadata;
|
||||||
|
|
||||||
flash.utils.setTimeout(this.onJsReady, 0);
|
flash.utils.setTimeout(this.on_js_ready, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function onJsReady():void {
|
private function on_stage_fullscreen(evt:FullScreenEvent):void {
|
||||||
|
if (!evt.fullScreen) {
|
||||||
|
execute_user_set_dar();
|
||||||
|
} else {
|
||||||
|
execute_user_enter_fullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function on_js_ready():void {
|
||||||
if (!flash.external.ExternalInterface.available) {
|
if (!flash.external.ExternalInterface.available) {
|
||||||
trace("js not ready, try later.");
|
trace("js not ready, try later.");
|
||||||
flash.utils.setTimeout(this.onJsReady, 100);
|
flash.utils.setTimeout(this.on_js_ready, 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +106,7 @@ package
|
||||||
flash.external.ExternalInterface.addCallback("__pause", this.js_call_pause);
|
flash.external.ExternalInterface.addCallback("__pause", this.js_call_pause);
|
||||||
flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume);
|
flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume);
|
||||||
flash.external.ExternalInterface.addCallback("__dar", this.js_call_dar);
|
flash.external.ExternalInterface.addCallback("__dar", this.js_call_dar);
|
||||||
|
flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size);
|
||||||
|
|
||||||
var code:int = flash.external.ExternalInterface.call(this.on_player_ready, this.id);
|
var code:int = flash.external.ExternalInterface.call(this.on_player_ready, this.id);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
@ -84,14 +114,14 @@ package
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function js_call_pause():int {
|
private function js_call_pause():int {
|
||||||
if (this.stream) {
|
if (this.stream) {
|
||||||
this.stream.pause();
|
this.stream.pause();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function js_call_resume():int {
|
private function js_call_resume():int {
|
||||||
if (this.stream) {
|
if (this.stream) {
|
||||||
this.stream.resume();
|
this.stream.resume();
|
||||||
}
|
}
|
||||||
|
@ -99,34 +129,54 @@ package
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to set the DAR, for example, DAR=16:9
|
* to set the DAR, for example, DAR=16:9
|
||||||
* @param num, for example, 9.
|
* @param num, for example, 9.
|
||||||
* @param den, for example, 16.
|
* use metadata height if 0.
|
||||||
*/
|
* use user specified height if -1.
|
||||||
public function js_call_dar(num:int, den:int):int {
|
* @param den, for example, 16.
|
||||||
if (this.video && num > 0 && den > 0 && this.video.width > 0) {
|
* use metadata width if 0.
|
||||||
// set DAR.
|
* use user specified width if -1.
|
||||||
// calc the height by DAR
|
*/
|
||||||
var _height:int = this.w * num / den;
|
private function js_call_dar(num:int, den:int):int {
|
||||||
if (_height <= this.h) {
|
dar_num = num;
|
||||||
this.video.width = this.w;
|
dar_den = den;
|
||||||
this.video.height = _height;
|
|
||||||
} else {
|
flash.utils.setTimeout(execute_user_set_dar, 0);
|
||||||
// height overflow, calc the width by DAR
|
|
||||||
var _width:int = this.h * den / num;
|
|
||||||
|
|
||||||
this.video.width = _width;
|
|
||||||
this.video.height = this.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// align center.
|
|
||||||
this.video.y = (this.h - this.video.height) / 2;
|
|
||||||
this.video.x = (this.w - this.video.width) / 2;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function js_call_stop():int {
|
/**
|
||||||
|
* set the fullscreen size data.
|
||||||
|
* @refer the refer fullscreen mode. it can be:
|
||||||
|
* video: use video orignal size.
|
||||||
|
* screen: use screen size to rescale video.
|
||||||
|
* @param percent, the rescale percent, where
|
||||||
|
* 100 means 100%.
|
||||||
|
*/
|
||||||
|
private function js_call_set_fs_size(refer:String, percent:int):int {
|
||||||
|
fs_refer = refer;
|
||||||
|
fs_percent = percent;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* js cannot enter the fullscreen mode, user must click to.
|
||||||
|
*/
|
||||||
|
private function on_user_click_video(evt:MouseEvent):void {
|
||||||
|
if (!this.stage.allowsFullScreen) {
|
||||||
|
trace("donot allow fullscreen.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enter fullscreen to get the fullscreen size correctly.
|
||||||
|
if (this.stage.displayState == StageDisplayState.FULL_SCREEN) {
|
||||||
|
this.stage.displayState = StageDisplayState.NORMAL;
|
||||||
|
} else {
|
||||||
|
this.stage.displayState = StageDisplayState.FULL_SCREEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function js_call_stop():int {
|
||||||
if (this.stream) {
|
if (this.stream) {
|
||||||
this.stream.close();
|
this.stream.close();
|
||||||
this.stream = null;
|
this.stream = null;
|
||||||
|
@ -143,17 +193,24 @@ package
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):int {
|
private function draw_black_background(_width:int, _height:int):void {
|
||||||
|
// draw black bg.
|
||||||
|
this.graphics.beginFill(0x00, 1.0);
|
||||||
|
this.graphics.drawRect(0, 0, _width, _height);
|
||||||
|
this.graphics.endFill();
|
||||||
|
|
||||||
|
// draw the fs mask.
|
||||||
|
this.fs_mask.graphics.beginFill(0xff0000, 0);
|
||||||
|
this.fs_mask.graphics.drawRect(0, 0, _width, _height);
|
||||||
|
this.fs_mask.graphics.endFill();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):int {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.w = _width;
|
this.w = _width;
|
||||||
this.h = _height;
|
this.h = _height;
|
||||||
trace("start to play url: " + this.url + ", w=" + this.w + ", h=" + this.h);
|
trace("start to play url: " + this.url + ", w=" + this.w + ", h=" + this.h);
|
||||||
|
|
||||||
// draw black bg.
|
|
||||||
this.graphics.beginFill(0x00, 1.0);
|
|
||||||
this.graphics.drawRect(0, 0, this.w, this.h);
|
|
||||||
this.graphics.endFill();
|
|
||||||
|
|
||||||
js_call_stop();
|
js_call_stop();
|
||||||
|
|
||||||
this.conn = new NetConnection();
|
this.conn = new NetConnection();
|
||||||
|
@ -184,6 +241,11 @@ package
|
||||||
video.attachNetStream(stream);
|
video.attachNetStream(stream);
|
||||||
video.smoothing = true;
|
video.smoothing = true;
|
||||||
addChild(video);
|
addChild(video);
|
||||||
|
|
||||||
|
draw_black_background(_width, _height);
|
||||||
|
|
||||||
|
// lowest layer, for mask to cover it.
|
||||||
|
setChildIndex(video, 0);
|
||||||
});
|
});
|
||||||
this.conn.connect(this.url.substr(0, this.url.lastIndexOf("/")));
|
this.conn.connect(this.url.substr(0, this.url.lastIndexOf("/")));
|
||||||
|
|
||||||
|
@ -204,26 +266,10 @@ package
|
||||||
contextMenu.customItems = customItems;
|
contextMenu.customItems = customItems;
|
||||||
|
|
||||||
// for js.
|
// for js.
|
||||||
var obj:Object = {
|
var obj:Object = get_video_size_object();
|
||||||
width: video.width,
|
|
||||||
height: video.height,
|
|
||||||
server: 'srs',
|
|
||||||
contributor: 'winlin'
|
|
||||||
};
|
|
||||||
|
|
||||||
if (metadata.hasOwnProperty("width")) {
|
obj.server = 'srs';
|
||||||
obj.width = metadata.width;
|
obj.contributor = 'winlin';
|
||||||
}
|
|
||||||
if (metadata.hasOwnProperty("height")) {
|
|
||||||
obj.height = metadata.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video.videoWidth > 0) {
|
|
||||||
obj.width = video.videoWidth;
|
|
||||||
}
|
|
||||||
if (video.videoHeight > 0) {
|
|
||||||
obj.height = video.videoHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metadata.hasOwnProperty("server")) {
|
if (metadata.hasOwnProperty("server")) {
|
||||||
obj.server = metadata.server;
|
obj.server = metadata.server;
|
||||||
|
@ -237,5 +283,139 @@ package
|
||||||
throw new Error("callback on_player_metadata failed. code=" + code);
|
throw new Error("callback on_player_metadata failed. code=" + code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the "right" size of video,
|
||||||
|
* 1. initialize with the original video object size.
|
||||||
|
* 2. override with metadata size if specified.
|
||||||
|
* 3. override with codec size if specified.
|
||||||
|
*/
|
||||||
|
private function get_video_size_object():Object {
|
||||||
|
var obj:Object = {
|
||||||
|
width: video.width,
|
||||||
|
height: video.height
|
||||||
|
};
|
||||||
|
|
||||||
|
// override with metadata size.
|
||||||
|
if (metadata.hasOwnProperty("width")) {
|
||||||
|
obj.width = metadata.width;
|
||||||
|
}
|
||||||
|
if (metadata.hasOwnProperty("height")) {
|
||||||
|
obj.height = metadata.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// override with codec size.
|
||||||
|
if (video.videoWidth > 0) {
|
||||||
|
obj.width = video.videoWidth;
|
||||||
|
}
|
||||||
|
if (video.videoHeight > 0) {
|
||||||
|
obj.height = video.videoHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* execute the enter fullscreen action.
|
||||||
|
*/
|
||||||
|
private function execute_user_enter_fullscreen():void {
|
||||||
|
if (!fs_refer || fs_percent <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// change to video size if refer to video.
|
||||||
|
var obj:Object = get_video_size_object();
|
||||||
|
|
||||||
|
// get the DAR
|
||||||
|
var num:int = dar_num;
|
||||||
|
var den:int = dar_den;
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
num = obj.height;
|
||||||
|
}
|
||||||
|
if (num == -1) {
|
||||||
|
num = this.stage.fullScreenHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (den == 0) {
|
||||||
|
den = obj.width;
|
||||||
|
}
|
||||||
|
if (den == -1) {
|
||||||
|
den = this.stage.fullScreenWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for refer is screen.
|
||||||
|
if (fs_refer == "screen") {
|
||||||
|
obj = {
|
||||||
|
width: this.stage.fullScreenWidth,
|
||||||
|
height: this.stage.fullScreenHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// rescale to fs
|
||||||
|
update_video_size(num, den, obj.width * fs_percent / 100, obj.height * fs_percent / 100, this.stage.fullScreenWidth, this.stage.fullScreenHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for user set dar, or leave fullscreen to recover the dar.
|
||||||
|
*/
|
||||||
|
private function execute_user_set_dar():void {
|
||||||
|
// get the DAR
|
||||||
|
var num:int = dar_num;
|
||||||
|
var den:int = dar_den;
|
||||||
|
|
||||||
|
var obj:Object = get_video_size_object();
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
num = obj.height;
|
||||||
|
}
|
||||||
|
if (num == -1) {
|
||||||
|
num = this.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (den == 0) {
|
||||||
|
den = obj.width;
|
||||||
|
}
|
||||||
|
if (den == -1) {
|
||||||
|
den = this.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_video_size(num, den, this.w, this.h, this.w, this.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the video width and height,
|
||||||
|
* according to the specifies DAR(den:num) and max size(w:h).
|
||||||
|
* set the position of video(x,y) specifies by size(sw:sh),
|
||||||
|
* and update the bg to size(sw:sh).
|
||||||
|
* @param _num/_den the DAR. use to rescale the player together with paper size.
|
||||||
|
* @param _w/_h the video draw paper size. used to rescale the player together with DAR.
|
||||||
|
* @param _sw/_wh the stage size, >= paper size. used to center the player.
|
||||||
|
*/
|
||||||
|
private function update_video_size(_num:int, _den:int, _w:int, _h:int, _sw:int, _sh:int):void {
|
||||||
|
if (!this.video || _num <= 0 || _den <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set DAR.
|
||||||
|
// calc the height by DAR
|
||||||
|
var _height:int = _w * _num / _den;
|
||||||
|
if (_height <= _h) {
|
||||||
|
this.video.width = _w;
|
||||||
|
this.video.height = _height;
|
||||||
|
} else {
|
||||||
|
// height overflow, calc the width by DAR
|
||||||
|
var _width:int = _h * _den / _num;
|
||||||
|
|
||||||
|
this.video.width = _width;
|
||||||
|
this.video.height = _h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// align center.
|
||||||
|
this.video.x = (_sw - this.video.width) / 2;
|
||||||
|
this.video.y = (_sh - this.video.height) / 2;
|
||||||
|
|
||||||
|
draw_black_background(_sw, _sh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue