效果:

视频分段好处显而易见,就是节省流量,因为看视频很多时候都不会看完,还有很多时候是跳着看的。还有的时候也许用户暂停视频出去买东西了。。。

本文不讨论flash rtmp直播流,例子用的是普通的http流,视频7分钟一段,播放至当前视频的90%时开始加载下一段。

原理很简单,就是伪视频流和对播放时间的判断,还有一些小的细节。

关于视频伪流技术(pseudo streaming)可以参考flowplayer的这篇介绍http://flash.flowplayer.org/plugins/streaming/pseudostreaming.html,简单说就是这个东西可以让用户不用等视频缓冲到后面就可以点击后面没缓冲的位置播放,这点很实用。

1.安装服务器视频模块,让服务器支持客户端发出的对视频相应帧的请求。我的是apache httpd

LoadModule flvx_module modules/mod_flvx.so
LoadModule h264_streaming_module modules/mod_h264_streaming.so

nginx也是在编译的时候添加nginx对这两个视频格式模块的支持参数。

2.这样客户端就是可以用有start参数的链接让服务器传输从相应帧开始的视频。

对于mp4,解析出

time 0
offset 217027
time 2.333
offset 361576
time 11.733
offset 1010319

。。。。

请求格式start= _frameInfo[frame].time

flv,f4v由于格式内没有对相应帧的索引,所以必须用flvtool或yamdi添加,添加后解析出

filepositions  5388,36263,65370,93925,。。。。。。

times  0.065,0.545,1.025,1.505,1.985,。。。。。。。。

请求格式start= _frameInfo.filepositions[frame])

as

main.as

 package
{
import flash.display.*;
import ui.*;
import flash.events.*;
import core.*;
import flash.geom.*; public class Youtube_player extends MovieClip
{
private var W:int = 360;
private var H:int = 266;
private var fullscreen:Boolean = true;
private var video:String;
private var thumbnail:String;
private var playing:Boolean = false;
private var load_relate:Boolean = false;
private var autoplay:Boolean = true;
private var cur_vl:VideoLoader;//当前videoloader
private var loader_arr:Array;
private var loading:Boolean = false;//是否在加载缓冲
private var fs:Boolean = false;
private var _nav_bar;
private var videoHeight:int;
private var videoWidth:int;
private var video_index:int = 0;
private var duration:int = 1232;//总时长
private var part_duration:int = 420;//每段长度
private var cur_total_time:int = 0;
private var v:VideoLoader;//视频操作的封装类
private var cur_i:int;//当前视频index
private var isPlay:Boolean; var arr=['http://localhost/twitter/videos/1.mp4?'+new Date().getTime(),'http://localhost/twitter/videos/3.mp4?'+new Date().getTime(),'http://localhost/twitter/videos/4.mp4?'+new Date().getTime()];
//var arr=['http://localhost/twitter/videos/2.flv?'+new Date().getTime(),'http://localhost/twitter/videos/3.flv?'+new Date().getTime(),'http://localhost/twitter/videos/4.flv?'+new Date().getTime()]; public function Youtube_player()
{
_load_config(this.loaderInfo);
_init();
_init_ui(W,H);
_init_events();
}
function resizeEvent(e:Event):void
{
_init_ui(stage.stageWidth, stage.stageHeight);
size_screen(W,H);//重绘ui
}
private function add_video_listener(i:int)
{
var vl:VideoLoader = loader_arr[i] as VideoLoader;
var vl1:VideoLoader = null;
if (i<arr.length-1)
{
vl1 = loader_arr[i + 1] as VideoLoader;
}
vl.volume(0);
if (! vl.hasEventListener("playProgress"))
{
vl.addEventListener("playProgress",function(){
if(vl.status=="NetStream.Seek.Notify")
buffering.visible = true;
else
buffering.visible = false;
var vl1_buffer_progress=0;
var a=vl.isFlv?cur_total_time+vl.videoTime:cur_total_time+vl.videoTime+vl.start;
if(vl.videoTime>1){
nav.progress_line.x=a/duration*nav.bar.width;
nav.notify.text=formatTime(a)+" / "+formatTime(duration);
}
if(vl1!=null&&!isNaN(vl1.bufferProgress)&&vl1.bufferProgress!=0){
vl1_buffer_progress=vl1.bufferProgress*vl1.totalTime;
}
var vl_buffer_progress=0;
if(!isNaN(vl.bufferProgress)){
vl_buffer_progress=vl.isFlv?vl.bufferProgress*(vl.totalTime-vl.start):vl.bufferProgress*vl.totalTime;
}
if(!isNaN(vl_buffer_progress)&&!isNaN(vl1_buffer_progress)){
if(i==arr.length-1||vl_buffer_progress!=0&&vl.isPlay){
nav.progressBar.width=(vl.start+vl1_buffer_progress+cur_total_time+vl_buffer_progress)/duration*nav.bar.width;
}
}
var prop=vl.isMp4?(loader_arr[cur_i].start+loader_arr[cur_i].videoTime)/(loader_arr[cur_i].totalTime+loader_arr[cur_i].start):vl.playProgress;
if(!loading&&prop>0.9&&prop<1){//播放到90%加载下一段
if(vl1!=null){
if(vl.isMp4){
vl1.metaData_loaded=false;
vl1.start=0;
}
vl1.load();
screen.setChildIndex(vl1.content,0);
vl1.pauseVideo();
loading=true;
}
}
});
}
if (! vl.hasEventListener("videoComplete"))
{
vl.addEventListener("videoComplete",function(){
if(vl1!=null){
screen.setChildIndex(vl1.content,screen.numChildren -1);
if(!vl1.isPlay)
vl1.pauseVideo();
cur_i=i+1;
cur_total_time=vl.isFlv?cur_total_time+vl.totalTime:cur_total_time+vl.totalTime+vl.start;
loading=false;
}
i++;
if(i<arr.length)
add_video_listener(i);
else{
nav.progressBar.visible=false;
nav.playingBar.visible=false;
new Recommend(stage,W,H);
}
});
}
}
private function _init()
{
v = new VideoLoader(arr[0],{name:"myVideo0",container:screen,width:360,height:240});
for (var i=1,len=arr.length; i<len; i++)
{
new VideoLoader(arr[i],{name:"myVideo" + i,container:screen,width:360,height:240});
}
loader_arr = VideoLoader.getLoader();
v.load();
cur_i = 0;
add_video_listener(0);//添加对每段视频的监听
v.addEventListener("videoStart",function(){
size_screen(W,H);
});
_nav_bar = new Nav_bar(nav,top_nav,overlay);
new Screen_size(stage,screen,top_nav.screen_size.size1,top_nav.screen_size.size2,top_nav.screen_size.size3);
}
private function progressBarEvent(e:MouseEvent):void//点击进度条
{
var point:Number = stage.mouseX;
var seekpoint:int = (point / nav.bar.width) * duration;
var index=Math.floor(seekpoint/part_duration);
var load_video:VideoLoader = loader_arr[index] as VideoLoader;
var load_video_buffer = loader_arr[index].bufferProgress * loader_arr[index].totalTime;
var seek_time = load_video.isFlv ? seekpoint % part_duration:seekpoint % part_duration - load_video.start;
if (isNaN(load_video_buffer)||(seekpoint%part_duration<load_video.start||seekpoint%part_duration>load_video.start+load_video_buffer))
{
if (cur_i!=index)
{
add_video_listener(index);
load_video.load(seekpoint % part_duration);
cur_total_time = cur_total_time + part_duration * (index - cur_i);
if (cur_i<loader_arr.length-1)
{
if (Math.abs(cur_i-index)>1)
{
loader_arr[cur_i + 1].netStream.close();
}
}
loader_arr[cur_i].netStream.close();
screen.setChildIndex(loader_arr[index].content,screen.numChildren -1);
}
else
{
load_video.load(seekpoint % part_duration);
screen.setChildIndex(load_video.content,screen.numChildren -1);
}
}
else
{
if (cur_i==index)
{
load_video.seekVideo(seek_time);
}
else
{
add_video_listener(index);
loader_arr[index].pauseVideo();
loader_arr[index].seekVideo(seek_time);
loader_arr[cur_i].netStream.close();
cur_total_time = cur_total_time + part_duration * (index - cur_i);
screen.setChildIndex(loader_arr[index].content,screen.numChildren -1);
loading = false;
}
}
cur_i = index;
}
private function _init_ui(W,H)
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
new Button(nav.playButton);
new Button(nav.pauseButton);
new Button(nav.fullscreen);
new Button(nav.volumn_btn);
new Button(nav.mute);
this.W = W;
this.H = H;
background.x = screen.x = overlay.x = 0;
background.y = screen.y = overlay.y = 0;
background.width = overlay.width = W;
background.height = overlay.height = H;
overlay.alpha = 0;
buffering.x = (W - buffering.width) * .5;
buffering.y = (H - buffering.height) * .5;
nav.y = H - 26;
top_nav.width = nav.bar.width = W;
top_nav.time.x = W - 70;
nav.pauseButton.y = nav.playButton.y;
nav.progressBar.x = nav.playingBar.x = 0;
nav.progressBar.y = nav.playingBar.y = nav.bar.y - 10;
nav.seeker_time.visible = false;
nav.seeker_time.y = nav.progressBar.y - 20;
nav.seeker_time.x = 0;
if (fullscreen)
{
nav.fullscreen.x = nav.bar.width - nav.fullscreen.width - 20;
}
else
{
nav.fullscreen.visible = false;
}
nav.playingBar.width = nav.bar.width;
nav.notify.x = nav.volumeBar.x + nav.volumeBar.width + 10;
nav.progressBar.width = W;
if (autoplay)
{
nav.playButton.visible = false;
}
else
{
nav.pauseButton.visible = false;
}
nav.volumn_btn.x = nav.volumeBar.x + 36;
nav.y = overlay.height - 26;
nav.progress_line.x = top_nav.y = -30;
nav.seeker_time.y = nav.progressBar.y - 20;
nav.seeker_time.x = 0;
nav.hover_line.y = nav.progress_line.y = nav.progressBar.y;
nav.setChildIndex(nav.progress_line,nav.numChildren-1);
nav.setChildIndex(nav.hover_line,nav.numChildren-1);
nav.hover_line.visible = false;
nav.hover_line.buttonMode = true;
nav.progress_line.buttonMode = true;
nav.progressBar.buttonMode = true;
nav.playingBar.buttonMode = true;
}
private function _init_events()
{
stage.addEventListener(Event.RESIZE, resizeEvent);
stage.addEventListener(Event.FULLSCREEN, resizeEvent);
stage.addEventListener(MouseEvent.MOUSE_MOVE,_nav_bar.nav_show);
nav.fullscreen.addEventListener(MouseEvent.CLICK, fullscreenEvent);
nav.progressBar.addEventListener(MouseEvent.MOUSE_OVER, seeker_time_show);
nav.playingBar.addEventListener(MouseEvent.MOUSE_OVER, seeker_time_show);
nav.progressBar.addEventListener(MouseEvent.MOUSE_MOVE, seeker_time_show);
nav.playingBar.addEventListener(MouseEvent.MOUSE_MOVE, seeker_time_show);
nav.progressBar.addEventListener(MouseEvent.MOUSE_OUT, seeker_time_hide);
nav.playingBar.addEventListener(MouseEvent.MOUSE_OUT, seeker_time_hide);
nav.playingBar.addEventListener(MouseEvent.CLICK, progressBarEvent);
nav.progressBar.addEventListener(MouseEvent.CLICK, progressBarEvent);
nav.playButton.addEventListener(MouseEvent.CLICK, playOrpauseEvent);
nav.pauseButton.addEventListener(MouseEvent.CLICK, playOrpauseEvent);
nav.volumeBar.addEventListener(MouseEvent.CLICK, volume_bar_click);
nav.mute.addEventListener(MouseEvent.CLICK, volumeEvent);
nav.volumn_btn.addEventListener(MouseEvent.MOUSE_DOWN, volumn_btn_mouse_down);
stage.addEventListener(MouseEvent.MOUSE_UP, volumn_btn_mouse_up);
top_nav.screen_size.size3.addEventListener(MouseEvent.CLICK,size3_handler);
}
private function size3_handler(e:MouseEvent):void
{
var proportion:Number = W / H;
var videoproportion:Number = loader_arr[cur_i].content.width / loader_arr[cur_i].content.height;
if (videoproportion >= proportion)
{
screen.width = W;
screen.height = W / videoproportion;
}
else
{
screen.width = H * videoproportion;
screen.height = H;
}
screen.x = (stage.stageWidth -screen.width) *0.5;
screen.y = (stage.stageHeight - screen.height) *0.5;
}
private function setVolume(newVolume:Number):void
{
loader_arr[cur_i].volume(newVolume);
nav.mute.gotoAndStop((newVolume > 0) ? 1 : 2);
}
private function volumeEvent(event:MouseEvent):void
{
setVolume(loader_arr[cur_i].mute());
}
private function volume_bar_click(event:MouseEvent):void
{
var volume = event.localX / 140;
nav.mute.gotoAndStop((volume > 0) ? 1 : 2);
loader_arr[cur_i].volume(new Number((volume.toFixed(2))));
nav.volumn_btn.x = nav.volumeBar.x + event.localX;
event.stopPropagation();
}
private function volumn_btn_mouse_down(e:Event)
{
var rect:Rectangle = new Rectangle(nav.volumeBar.x,nav.volumn_btn.y);
rect.width = nav.volumeBar.width - nav.volumn_btn.width;
rect.height = 0;
e.target.startDrag(false,rect);
nav.volumn_btn.addEventListener(MouseEvent.MOUSE_MOVE, volumn_btn_mouse_move);
e.stopPropagation();
}
private function volumn_btn_mouse_move(event:MouseEvent):void
{
var volume=(nav.volumn_btn.x-nav.volumeBar.x)/(140-nav.volumn_btn.width);
nav.mute.gotoAndStop((volume > 0) ? 1 : 2);
loader_arr[cur_i].volume(new Number((volume.toFixed(2))));
event.stopPropagation();
}
private function volumn_btn_mouse_up(event:MouseEvent):void
{
nav.volumn_btn.stopDrag();
nav.volumn_btn.removeEventListener(MouseEvent.MOUSE_MOVE, volumn_btn_mouse_move);
event.stopPropagation();
}
private function playOrpauseEvent(event:MouseEvent):void
{
isPlay = loader_arr[cur_i].pauseVideo();
nav.playButton.visible = isPlay;
nav.pauseButton.visible = ! isPlay;
}
private function _load_config(li:LoaderInfo)
{
video = this.loaderInfo.parameters.video;
thumbnail = this.loaderInfo.parameters.thumbnail;
autoplay = this.loaderInfo.parameters.autoplay == 1;
load_relate = this.loaderInfo.parameters.load_relate;
W=this.loaderInfo.parameters.width;
H=this.loaderInfo.parameters.height;
}
private function size_screen(W:int,H:int):void
{
top_nav.time.x = W - 70;
top_nav.screen_size.size2.gotoAndStop(1);
top_nav.screen_size.size3.gotoAndStop(1);
top_nav.screen_size.size1.gotoAndStop(1);
top_nav.screen_size.size2.graphics.clear();
top_nav.screen_size.size3.graphics.clear();
top_nav.screen_size.size1.graphics.clear();
if (fs)
{
top_nav.visible = true;
var proportion:Number = W / H;
var videoproportion:Number = loader_arr[cur_i].content.width / loader_arr[cur_i].content.height;
if (videoproportion >= proportion)
{//<= (H / W)
screen.width = W;
screen.height = W / videoproportion;
}
else
{
screen.width = H * videoproportion;
screen.height = H;
}
top_nav.screen_size.size3.gotoAndStop(2);
}
else
{
top_nav.visible = false;
screen.width = loader_arr[cur_i].content.width;
screen.height = loader_arr[cur_i].content.height;
}
screen.x = (stage.stageWidth -screen.width) *0.5;
screen.y = (stage.stageHeight - screen.height) *0.5;
}
public function fullscreenEvent(e:Event):void
{
if (stage.displayState == StageDisplayState.FULL_SCREEN)
{
fs = false;
stage.displayState = StageDisplayState.NORMAL;
}
else
{
fs = true;
stage.displayState = StageDisplayState.FULL_SCREEN;
}
}
private function seeker_time_show(e:MouseEvent):void
{
var target_x = stage.mouseX;
nav.hover_line.x = target_x;
if (15<target_x&&target_x<W-15)
{
nav.hover_line.visible = true;
nav.seeker_time.visible = true;
nav.seeker_time.x = target_x;
nav.seeker_time.mouseon_time.text = formatTime(stage.mouseX / W * duration);
}
}
private function seeker_time_hide(e:MouseEvent):void
{
nav.hover_line.visible = false;
nav.seeker_time.visible = false;
}
private function formatTime(time:Number):String
{
if (time > 0)
{
var integer:String = String((time / 60) >> 0);
var decimal:String = String((time % 60) >> 0);
return ((integer.length < 2) ? "0" + integer : integer) + ":" + ((decimal.length < 2) ? "0" + decimal : decimal);
}
else
{
return String("00:00");
}
}
}
}

VideoLoader.as

 package core
{
import flash.display.*;
import flash.net.*;
import flash.media.*;
import flash.events.*;
import flash.utils.*; public class VideoLoader extends Shape
{
private var nc:NetConnection;
private var _ns:NetStream;
private var st:SoundTransform;
private var _url:String;
private var vars:Object;
private var v:Video;
private var _status:String;
private var togglepause:Boolean = false;
private var _duration:int;
private static var _loader = [];
private var _frameInfo:Object;
private var _start:Number = 0;
private var _metaData_loaded:Boolean = false;
private var _volcache:Number = 0;
private var _isMp4:Boolean = false;
private var _isFlv:Boolean = false; public function VideoLoader(url:String,vars:Object=null)
{
nc = new NetConnection ;
nc.connect(null);
_ns = new NetStream(nc);
_ns.addEventListener(NetStatusEvent.NET_STATUS,nsEvent);
_ns.client = {onMetaData:this._metaDataHandler};
_ns.bufferTime = 1;
st = new SoundTransform ;
v = new Video ;
v.attachNetStream(_ns);
getVideoType(url);
this._url = url;
this.vars = vars;
_loader.push(this);
v.smoothing = true;
vars.container.addChildAt(v,0);
}
private function nsEvent(e:NetStatusEvent):void
{
if ((_status != e.info.code))
{
switch (e.info.code)
{
case "NetConnection.Connect.Success" :
break;
case "NetStream.Play.Stop" :
stopVideo();
break;
case "NetStream.Play.Start" :
break;
}
_status = e.info.code;
_render();
}
}
public function mute():Number
{
if (_volcache)
{
st.volume = _volcache;
_ns.soundTransform = st;
_volcache = 0;
}
else
{
_volcache = st.volume;
st.volume = 0;
_ns.soundTransform = st;
}
return st.volume;
}
public function load(start:Number=0):void
{
//trace(_metaData_loaded);
_start = start;
if (nc.connected)
{
if (_metaData_loaded)
{
var frame:Number = _isFlv ? get_nearest_keyframe(_start,_frameInfo.times):get_nearest_seekpoint(_start,_frameInfo);
if (_isFlv)
{
_ns.play(((_url + "&start=") + _frameInfo.filepositions[frame]));
}
else
{
_ns.play(((_url + "&start=") + _frameInfo[frame].time));
}
}
else
{
_ns.play(_url);
}
}
else
{
_ns.play(_url);
}
}
private function _metaDataHandler(i:Object):void
{
// for (var j=0,len=i['seekpoints'].length; j<len; j++)
// {
// var h = i['seekpoints'][j];
// for (var k in h)
// {
// trace(k+" "+h[k]);
// }
// }
// for (var j in i['keyframes'])
// {
// trace(((j + " ") + i['keyframes'][j]));
// }
_duration = i.duration;
_frameInfo = _isFlv ? i['keyframes']:i['seekpoints'];
if (typeof vars.width == 'undefined')
{
v.width = i.width;
}
if (typeof vars.height == 'undefined')
{
v.height = i.height;
}
if ((_start != 0&&!_metaData_loaded))
{
_ns.close();
var frame:Number = _isFlv ? get_nearest_keyframe(_start,_frameInfo.times):get_nearest_seekpoint(_start,_frameInfo);
if (_isFlv)
{
_ns.play(((_url + "&start=") + _frameInfo.filepositions[frame]));
}
else
{
_ns.play(((_url + "&start=") + _frameInfo[frame].time));
}
}
_metaData_loaded = true;
}
private function get_nearest_seekpoint(second:Number,seekpoints)
{
var index1 = seekpoints.length - 1;
var index2 = seekpoints.length - 1;
for (var i = 0; i != seekpoints.length; i++)
{
if (seekpoints[i]["time"] < second)
{
index1 = i;
}
else
{
index2 = i;
break;
}
}
if (((second - seekpoints[index1]["time"]) < seekpoints[index2]["time"] - second))
{
return index1;
}
else
{
return index2;
}
}
private function get_nearest_keyframe(second:Number,keytimes)
{
var index1 = 0;
var index2 = 0;
for (var i = 0; i != keytimes.length; i++)
{
if (keytimes[i] < second)
{
index1 = i;
}
else
{
index2 = i;
break;
}
}
if (((second - keytimes[index1]) < keytimes[index2] - second))
{
return index1;
}
else
{
return index2;
}
}
private function getVideoType(url:String):void
{
var index = url.lastIndexOf(".flv");
if ((index != -1))
{
_isFlv = true;
}
else
{
_isFlv = false;
}
_isMp4 = ! _isFlv;
}
public function get isFlv():Boolean
{
return _isFlv;
}
public function get isMp4():Boolean
{
return _isMp4;
}
public function pauseVideo():Boolean
{
if (togglepause)
{
togglepause = false;
_ns.resume();
}
else
{
togglepause = true;
_ns.pause();
}
return togglepause;
}
public function volume(vol:Number)
{
st.volume = vol;
_ns.soundTransform = st;
}
public function stopVideo():void
{
this.dispatchEvent(new Event("videoComplete"));
_ns.close();
_metaData_loaded = false;
}
private function _render():void
{
var timer:Timer = new Timer(100);
var _this = this;
this.dispatchEvent(new Event("videoStart"));
var timerEvent = function(e:TimerEvent):void
{
_this.dispatchEvent(new Event("playProgress"));
};
timer.addEventListener(TimerEvent.TIMER,timerEvent);
timer.start();
}
public function seekVideo(point:Number):void
{
_ns.seek(point);
}
public function get videoPaused():Boolean
{
return togglepause;
}
public function get content():Video
{
return v;
}
public function get playProgress():Number
{
return _ns.time / _duration;
}
public function get bufferProgress():Number
{
return _ns ? _ns.bytesLoaded / _ns.bytesTotal:1;
}
public function get videoTime():Number
{
return _ns ? _ns.time:0;
}
public function get totalTime():Number
{
return _duration;
}
public static function getLoader():Array
{
return _loader;
}
public function get netStream():NetStream
{
return _ns;
}
public function set url(url:String):void
{
getVideoType(url);
_url = url;
}
public function get isPlay():Boolean
{
return !togglepause;
}
public function set metaData_loaded(metaData_loaded:Boolean):void
{
this._metaData_loaded=metaData_loaded;
}
public function get status():String
{
return _status;
}
public function get frameInfo():Object
{
return _frameInfo;
}
public function get start():Number
{
return _start;
}
public function set start(start:Number):void
{
this._start = start;
} }
}

因为嫌弃greensocks的loadermax里面的videoloader太大了,自己就重写了个。

题外话

事实上,如果开启了优酷客户端的加速器去网页上看优酷,可以看到优酷也是分了段的,也会发出1.flv?start=100那种请求。而不加速器就会是下图的种子请求

链接类似于:

http://27.221.48.210/youku/6571EC9C9743582E25E8A83AE9/030002070250ECC0BDF242023AEBCA6C8500D8-AB84-D3E6-1355-AD3E89D20E76.flv?nk=410723804503_23592369908&ns=11949300_2673200&special=true

优酷视频地址分析参见http://www.cnblogs.com/keygle/p/3829653.html,, http://www.cnblogs.com/zhaojunjie/p/4009192.html

可以看出优酷是用了苹果的m3u8.m3u8将那些5-10秒的分段小视频通过索引组织起来,而且可以调整适应码率。

下面问题来了,flash怎么解析m3u8..参见http://player.sewise.com/a/yingyongshili/20140425/7.html.

这个player实际是用了osmf和HLSProvider的m3u8解析,调用起来实际上也很简单.这样就大大的增加了m3u8的适用范围。缺点就是至少增加了150k的体积。

本屌的另一篇文章 小巧的http live streaming m3u8播放器

转载请注明 TheViper   http://www.cnblogs.com/TheViper

 

分段播放的flash播放器的更多相关文章

  1. eletron 播放rtmp flash 播放器问题

    1 安装 flash https://www.flash.cn/ 2 man.js 配置 参考 https://newsn.net/say/electron-flash-win.html 3 播放器 ...

  2. flash视频器播放器代码

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  3. flash播放器遮挡页面中元素问题解决

    今天在做一个包含Flash播放器的页面弹出效果时发现Flash播放器总是跑到页面最上层,发现这个问题与Flash的”wmode”属性有关,至于该元素详细此处不做记录,解决办法如下: IE:加入参数:& ...

  4. flash播放器插件与flash播放器的区别

    flash插件是一个网页ActiveX控件,而flash播放器是一个exe的可执行程序.前者用于播放网页中的falsh动画,而后者用于播放本地swf格式文件.

  5. 我们计划为EasyDSS定制开发一款超低延时的EasyPlayer Flash播放器

    现象 最近团队在做EasyDSS RTMP流媒体服务器开发的过程中,遇到了一个关于延时累积的问题,先大概描述一下过程: 在EasyRTMP Android进行长时间的RTMP推流压力测试,在EasyD ...

  6. 浏览器文档播放Shockwave Flash 插件问题

    浏览器被提示shockwave flash crashed怎么办?在使用浏览器的时候经常被提示shockwave flash crashed,flash插件崩溃,网页就会出现一些无法显示的文件,下面绿 ...

  7. EasyDSS RTMP流媒体服务器videojs flash播放RTMP/HLS提示错误的解决方案

    本文转自EasyDSS团队成员StarIT的博客:http://blog.csdn.net/staritstarit/article/details/73692715 问题 在博客<EasyDS ...

  8. Flash播放控件属性详解

    Flash 播放控件属性详解 一.属性篇 1.AlignMode(读写)  语法:AlignMode As Long  说明:对齐方式(与SAlign 属性联动).当控件的长宽比例与影片不一致且WMo ...

  9. 遭遇flash播放mp3诡异问题

    在部分ie10+flash player 播放mp3,播放第二句话时,中断无法正常播放,(客户的机器上),自己公司的机器测试了几个,都没发现这个问题.其它浏览器(chrome,firefox)也没发现 ...

随机推荐

  1. 使用Maven Profile实现多环境构建

    在开发过程中,我们的软件会面对不同的运行环境,比如开发环境.测试环境.生产环境,而我们的软件在不同的环境中,有的配置可能会不一样,比如数据源配置.日志文件配置.以及一些软件运行过程中的基本配置,那每次 ...

  2. Python Beautiful Soup模块的安装

    以安装Beautifulsoup4为例: 1.到网站上下载:http://www.crummy.com/software/BeautifulSoup/bs4/download/ 2.解压文件到C:\P ...

  3. Java AES加密

    Java AES 加密 加密 /** * * @description 加密 * * @param content 需要加密的内容 * @param password 加密密码 * @return * ...

  4. 黄聪:WordPress 的 Hook 机制与原理(add_action、add_filter)

    稍有接触过 WordPress 主题或插件制作修改的朋友,对 WordPress 的Hook机制应该不陌生,但通常刚接触WordPress Hook 的新手,对其运作原理可能会有点混乱或模糊.本文针对 ...

  5. wordpress主题结构_源码

    WordPress博客主题的工作机制 WordPress主题由一系列模板文件组成,每个文件分别控制主题的特定区域.无论你处于哪个页面都能看到的网站的静态部分,由header文件.sidebar和foo ...

  6. 单选按钮选中js的处理

    function FinancialinfosetController($scope, $http, $timeout, $location, $rootScope, $routeParams) { ...

  7. unity客户端与c++服务器之间的简单通讯_1

    // 服务器 # pragma once using namespace std; # include <iostream> # include <string> # incl ...

  8. SparkSql官方文档中文翻译(java版本)

    1 概述(Overview) 2 DataFrames 2.1 入口:SQLContext(Starting Point: SQLContext) 2.2 创建DataFrames(Creating ...

  9. Spark工程开发常用函数与方法(Scala语言)

    import org.apache.spark.{SparkContext, SparkConf}import org.apache.spark.sql.{SaveMode, DataFrame}im ...

  10. PLSQL_性能优化系列06_Oracle Soft Parse / Hard Parse软硬解析

    2014-08-11 Createed By BaoXinjian