Quicktime是一个跨浏览器的播放插件,可以实现RTSP视频直播,可用于电视直播或视频监控平台。本文主要讲了关于播放器如何实现直播、事件响应、播放器全屏、动态修改播放路径等问题。
需要准备的软件:quicktime安装文件、RTSP模拟器(或VLC播放器)。
以下是我的实现方式:
1. 播放器HTML静态代码
02 |
<!--[if IE]><object id="qt_event_source" classid="clsid:CB927D12-4FF7-4a9e-A169-56E4B8A75598" style="display:none;"></object><![endif]--> |
03 |
< object classid = "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width = "640" height = "480" codebase = "http://www.apple.com/qtactivex/qtplugin.cab#version=7,6,9,0" standby = "控件加载中..." name = "QT_OBJ" id = "QT_OBJ" style = "behavior:url(#qt_event_source);overflow:hidden;" > |
04 |
< param name = "src" value = "ress/preview.mov" /> |
05 |
<!-- <param name="qtsrc" value="rtsp://"/> --> |
06 |
< param name = "enablejavascript" value = "true" /> |
07 |
< param name = "postdomevents" value = "true" /> |
08 |
< param name = "controller" value = "false" /> |
09 |
< param name = "scale" value = "tofit" /> |
10 |
< param name = "kioskmode" value = "true" /> |
11 |
< param name = "bgcolor" value = "#000000" /> |
12 |
< param name = "qtsrcdontusebrowser" value = "true" /> |
13 |
< param name = "cache" value = "false" /> |
15 |
< embed src = "ress/preview.mov" width = "640" height = "480" pluginspage = "http://www.apple.com/quicktime/download/" name = "QT_EMB" id = "QT_EMB" enablejavascript = "true" postdomevents = "true" controller = "false" scale = "tofit" kioskmode = "true" bgcolor = "#000000" qtsrcdontusebrowser = "true" cache = "false" style = "overflow:hidden;" ></ embed > |
代码说明:
1. object 用于IE浏览器,而 embed 用于非IE浏览器;
2. qt_event_source 对象是为了给IE浏览器注册事件,通过style( style="behavior:url(#qt_event_source);overflow:hidden;")绑定行为;
3. src="ress/preview.mov" 用于在页面加载后初始化控件,因为在上述代码中没有初始化 qtsrc 直播路径(便于动态切换播放路径);
4. kioskmode="true" 隐藏播放器右键菜单。
2. Javascript代码实现(部分)
021 |
setPlayerParameters : function (url) { |
024 |
var qt = Player.object; |
025 |
if (!$.browser.msie && !qt.SetURL) { |
029 |
qt.SetControllerVisible( false ); |
030 |
qt.SetKioskMode( true ); |
032 |
qt.SetBgColor( '#ffffff' ); |
035 |
alert( 'resetPlayerParameters - ' + e.toString()); |
044 |
setRate : function () { |
046 |
Player.object.SetRate(10); |
049 |
* 初始化播放路径,如:rtsp://192.168.0.100:554/3 |
054 |
initGUrl : function (stream) { |
055 |
var host = location.hostname; |
056 |
var port = '' ; // ':'+554; |
057 |
var url = [ 'rtsp://' , host, port, '/' , stream ].join( '' ); |
061 |
* 注册事件,为IE浏览器注册时要多加个'on'在事件前面 |
063 |
regQuickTimeEvents : function () { |
064 |
var listerners = Player.listerners; |
065 |
if (document.addEventListener) { |
066 |
var obj = document.QT_EMB; |
069 |
obj.addEventListener( "qt_timechanged" , |
070 |
listerners._qt_timechanged_listerner); |
071 |
obj.addEventListener( "qt_stalled" , |
072 |
listerners._qt_stalled_listerner); |
074 |
.addEventListener( "qt_error" , |
075 |
listerners._qt_error_listerner); |
078 |
var obj = document.QT_OBJ; |
081 |
obj.attachEvent( "onqt_timechanged" , |
082 |
listerners._qt_timechanged_listerner); |
083 |
obj.attachEvent( "onqt_stalled" , |
084 |
listerners._qt_stalled_listerner); |
085 |
obj.attachEvent( "onqt_error" , listerners._qt_error_listerner); |
091 |
_qt_timechanged_listerner : function () { |
093 |
var qt = Player.object; |
094 |
if (!$.browser.msie && !qt.SetRate) { |
097 |
// 通过设置播放率快速播放来消耗缓存达到实时播放 |
099 |
qt.SetBgColor( '#000000' ); |
100 |
Player.getStreamWidthHeight(qt, true ); |
104 |
_qt_stalled_listerner : function () { |
105 |
alert( '连接已终断,正在尝试重新连接...' ); |
107 |
_qt_error_listerner : function () { |
108 |
alert( '播放时发生错误,请刷新页面或重新登录来解决此问题!' ); |
112 |
* 将视频填充到当前播放器大小一致,并维持原始长宽比 |
114 |
* SetRectangle参数中每个值都必须是整形,不能有小数 在计算时可能出现高度或宽度相差一个像素 |
116 |
adaptation : function () { |
120 |
var object = Player.object; |
122 |
var w_box = qt.width(); |
123 |
var h_box = qt.height(); |
124 |
var wh = Player.getStreamWidthHeight(object, false ); |
127 |
var w_per = wh.width || 640; |
128 |
var h_per = wh.height || 480; |
129 |
var rect = [ 0, 0, 640, 480 ]; |
130 |
var dw = w_per / w_box; |
131 |
var dh = h_per / h_box; |
133 |
rect[2] = parseInt(w_box); |
134 |
rect[3] = parseInt(h_box); |
135 |
} else if (dw > dh) { |
136 |
var h_per_new = h_per / dw; |
137 |
var offset = (h_box - h_per_new) / 2; |
138 |
rect[1] = parseInt(offset); |
139 |
rect[2] = parseInt(w_box); |
140 |
rect[3] = parseInt(h_per_new + offset); |
142 |
var w_per_new = w_per / dh; |
143 |
var offset = (w_box - w_per_new) / 2; |
144 |
rect[0] = parseInt(offset); |
145 |
rect[2] = parseInt(w_per_new + offset); |
146 |
rect[3] = parseInt(h_box); |
148 |
if (!$.browser.msie && !object.SetRectangle) { |
151 |
object.SetRectangle(rect.join( ',' )); |
161 |
* 是否将 Player.stream中的参数重写 |
164 |
getStreamWidthHeight : function (playerObj, isFlash) { |
168 |
if (!$.browser.msie && !playerObj.GetRectangle) { |
171 |
var rect = playerObj.GetRectangle().split( ',' ); |
172 |
var width = parseInt(rect[2]) - parseInt(rect[0]); |
173 |
var height = parseInt(rect[3]) - parseInt(rect[1]); |
175 |
this .stream.width = width; |
176 |
this .stream.height = height; |
179 |
width : width || this .stream.width, |
180 |
height : height || this .stream.height |
187 |
* @param{Object} el 被放大对象 |
189 |
requestFullScreen : function (el) { |
190 |
var agent = '' ; // TODO 获取浏览器名称 |
193 |
// 支持大多数浏览器全屏功能,除了FCK IE! |
194 |
var requestMethod = el.requestFullScreen || el.webkitRequestFullScreen |
195 |
|| el.mozRequestFullScreen || el.msRequestFullScreen; |
198 |
requestMethod.call(el); |
199 |
var stream = Player.stream; |
200 |
el.SetRectangle([ 0, 0, stream.width, stream.height ].join( ',' )); |
201 |
obj.width(window.screen.width); |
202 |
obj.height(window.screen.height); |
205 |
if (agent.name == 'safari' ) { |
代码说明:
1. 上述代码并不完整,需要根据实际情况作相应调整;
2. 基本使用方式:Player.regQuickTimeEvents().setPlayerParameters(url);
3. Quicktime在播放RTSP时会有3-5秒延迟,这是缓存所至,但控件没有提供相应清空缓存方法,只有通过SetRate()来设置播放速率来清除缓存。
播放截图:

可能出现的问题:
1. 在显示/隐藏播放控件、全屏/恢复时会导致重新加载视频;
3. 相关资源
1. JavaScript Scripting Guide for QuickTime
2. QuickTime: Embed Tag Attributes
3. QuickTime fullscreen ( 很帅的东西)
4. Quicktime插件函数列表
AddCuePoint(time, fcnName, pause) |
void |
|
Clear() |
void |
|
GetAutoPlay() |
Number |
|
GetBgColor() |
String |
获取播放器背景颜色 |
GetChapterCount() |
Number |
|
GetChapterName(chapterNum) |
String |
|
GetComponentVersion(type, subType, manufacturer) |
String |
|
GetControllerVisible() |
Number |
|
GetCurrentChapterIndex() |
Number |
|
GetDuration() |
Number |
|
GetEndTime() |
Number |
|
GetFieldOfView() |
Number |
|
GetHotspotTarget(hotspotID) |
String |
|
GetHotspotUrl(hotspotID) |
String |
|
GetHREF() |
Number |
|
GetIsLooping() |
Number |
|
GetIsQuickTimeRegistered() |
Number |
|
GetIsVRMovie() |
Number |
|
GetKioskMode() |
Number |
|
GetLanguage() |
String |
|
GetLoopIsPalindrome() |
Number |
|
GetMatrix() |
String |
|
GetMaxBytesLoaded() |
Number |
|
GetMaxTimeLoaded() |
Number |
|
GetMIMEType() |
String |
|
GetMovieID() |
Number |
|
GetMovieName() |
String |
|
GetMovieSize() |
Number |
|
GetMute() |
Number |
|
GetNodeCount() |
Number |
|
GetNodeID() |
Number |
|
GetPanAngle() |
Number |
|
GetPlayEveryFrame() |
Number |
|
GetPluginStatus() |
String |
|
GetPluginVersion() |
String |
|
GetQTNEXTUrl(index) |
String |
|
GetQuickTimeConnectionSpeed() |
Number |
|
GetQuickTimeLanguage() |
String |
|
GetQuickTimeVersion() |
String |
|
GetRate() |
Number |
|
GetRectangle() |
String |
|
GetResetPropertiesOnReload() |
Number |
|
GetSpriteTrackVariable(trackIndex, variableIndex) |
String |
|
GetStartTime() |
Number |
|
GetTarget() |
String |
|
GetTiltAngle() |
Number |
|
GetTime() |
Number |
|
GetTimeScale() |
Number |
|
GetTrackCount() |
Number |
|
GetTrackEnabled(index) |
Number |
|
GetTrackName(index) |
String |
|
GetTrackType(index) |
String |
|
GetURL() |
String |
|
GetUserData(type) |
String |
|
GetVolume() |
Number |
|
GoPreviousNode() |
void |
|
GoToChapter(chapterName) |
void |
|
Hide() |
void |
|
Play() |
void |
|
RemoveCuePoint(time, fcnName) |
void |
|
Rewind() |
void |
|
SendSpriteEvent(trackIndex, spriteID, messageID) |
void |
|
SetAutoPlay(autoPlay) |
void |
|
SetBgColor(color) |
void |
|
SetControllerVisible(visible) |
void |
|
SetCurrentChapterIndex(chapterIndex) |
void |
|
SetEndTime(time) |
void |
|
SetFieldOfView(fov) |
void |
|
SetHotspotTarget(hotspotID, target) |
void |
|
SetHotspotUrl(hotspotID, url) |
void |
|
SetHREF(url) |
void |
|
SetIsLooping(loop) |
void |
|
SetKioskMode(kioskMode) |
void |
|
SetLanguage(language) |
void |
|
SetLoopIsPalindrome(loop) |
void |
|
SetMatrix(matrix) |
void |
|
SetMovieID(movieID) |
void |
|
SetMovieName(movieName) |
void |
|
SetMute(mute) |
void |
|
SetNodeID(id) |
void |
|
SetPanAngle(angle) |
void |
|
SetPlayEveryFrame(playAll) |
void |
|
SetQTNEXTUrl(index, url) |
void |
|
SetRate(rate) |
void |
设置播放速度。可设置较大速度以此作清除缓存的辅助工具。 |
SetRectangle(rect) |
void |
设置显示画面大小和位置。 |
SetResetPropertiesOnReload(reset) |
void |
|
SetSpriteTrackVariable(trackIndex, variableIndex, value) |
void |
|
SetStartTime(time) |
void |
|
SetTarget(target) |
void |
|
SetTiltAngle(angle) |
void |
|
SetTime(time) |
void |
|
SetTrackEnabled(index, enabled) |
void |
|
SetURL(url) |
void |
|
SetVolume(volume) |
void |
|
Show() |
void |
|
ShowDefaultView() |
void |
|
Step(count) |
void |
|
Stop() |
void |
|
- 前端视频直播技术总结及video.js在h5页面中的应用
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/12557070.html,多谢,=.=~ (如果对你有帮助的话请帮我点个赞啦) 目前有一个需求是在 ...
- 【腾讯bugly干货分享】HTML 5 视频直播一站式扫盲
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1277 视频直 ...
- 【腾讯Bugly干货分享】H5 视频直播那些事
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...
- iOS中 视频直播功能-流媒体的使用(详解)韩俊强的CSDN博客
上一篇博客:(流媒体实现视频播放和下载功能):http://blog.csdn.net/qq_31810357/article/details/50574914 最近视频直播功能比较火,处于需求,研究 ...
- HLS视频直播
HTTP Live Streaming (HLS) 苹果官方对于视频直播服务提出了 HLS 解决方案,该方案主要适用范围在于: 使用 iPhone .iPod touch. iPad 以及 Apple ...
- Android&iOS视频直播之旅
现在的移动互联网时代,大家的网速真是越来越快,高带宽的WIFI和覆盖率极大的4G,4G+把手机观看视频直播推上了风口浪尖,越来越多的应用在玩手机视频直播,我们做的应用里也要嵌入视频直播. 这篇文章里我 ...
- 使用ckplayer搭建rtmp视频直播应用
视频直播才有的是RTMP协议进行视频实时流传输,在这里我们用到的软件都是 adobe 公司的一个是:Flash Media Server4 另一个是flash media live encoder 这 ...
- 基于live555的视频直播 DM368IPNC RTSP分析
因需要,从个人的理解顺序和需求角度对live555的分析与开发整理,包含RTSP Server与RTSP Client.如何直播H.264流与JPEG流等,均进行了探讨,对live555的初学者有一定 ...
- H5 视频直播相关技术
一.移动视频直播发展 大家首先来看下面这张图: 可以看到,直播从 PC 到一直发展到移动端,越来越多的直播类 App 上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以 ...
随机推荐
- ZooKeeper学习总结 第二篇:ZooKeeper深入探讨(转载)
其实zookeeper系列的学习总结很早就写完了,这段时间在准备找工作的事情,就一直没有更新了.下边给大家送上,文中如有不恰当的地方,欢迎给予指证,不胜感谢!. 1. 数据模型 1.1. 只适合存储小 ...
- NOI 题库 2727
2727 仙岛求药 描述 少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶.叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处.迷阵由M×N ...
- YACC和BISON学习心得
最近学习了YACC和BISON两个工具,参考书籍<YACC和BISON>,通过里面的例子,明白了如何编写自己的解释性语言.
- C语言_第一章
1. 计算机能直接识别和接受的二进制代码称为 机器指令——>(集合) 机器语言. 2. 输出C #include<stdio.h> int main(){ printf(&q ...
- Unity3d与Android交互
先看下效果 你一定会说,然并卵! 没错,这里只是一个最简单的例子,unity与android activity 互相传参数. 玩过手游的都知道,在你要为你心爱的游戏角色准备花钱买钻石,点击购买的时候, ...
- centos使用yum安装软件的时候出现了undefined symbol: CRYPTO_set_locking_callback
1.问题 在CentOS下使用yum安装软件,结果出现了下面的错误提示: # yum installThere was a problem importing one of the Python mo ...
- Velocity 语法(转)
一.基本语法 1."#"用来标识Velocity的脚本语句,包括#set.#if .#else.#end.#foreach.#end.#iinclude.#parse.#macro ...
- 【KMP算法】字符串匹配
一.问题 给定两个字符串S(原串)和(模式串)T,找出T在S中出现的位置. 二.朴素算法 当S[i] != T[j]时,把T往后移一位,回溯S的位置并重新开始比较. (1) 成功匹配的部分(AB ...
- Python实战:下载鬼灵报告有声小说
在家无聊,想看看小说,不过看的眼睛痛,就想着下个有声小说来听听.但风上找到的都是要一集一集下,还得重命名,122集啊,点到什么时候. 写个批处理下载的脚本.记录下过程. 一.老套路了,找到下载URL. ...
- HTML 5 画布(canvas)
canvas 元素使用 JavaScript 在网页上绘制图像,本身是没有绘图能力. canvas 是一个矩形区域,可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形.字符以及添加图像的 ...