Quicktime是一个跨浏览器的播放插件,可以实现RTSP视频直播,可用于电视直播或视频监控平台。本文主要讲了关于播放器如何实现直播、事件响应、播放器全屏、动态修改播放路径等问题。
需要准备的软件:quicktime安装文件、RTSP模拟器(或VLC播放器)。
以下是我的实现方式:
01 |
<div
id="player"> |
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"/> |
14 |
<!-- qtsrc="" --> |
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> |
16 |
</object> |
17 |
</div> |
代码说明:
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" 隐藏播放器右键菜单。
001 |
var Player = { |
002 |
/** |
003 |
* 播放器对象 |
004 |
*/ |
005 |
object : null, |
006 |
stream : { |
007 |
/** |
008 |
* 视频初始化原始宽度 |
009 |
*/ |
010 |
width : 640, |
011 |
/** |
012 |
* 视频初始化原始高度 |
013 |
*/ |
014 |
height : 480 |
015 |
}, |
016 |
/** |
017 |
* 设置播放路径 |
018 |
* |
019 |
* @param url |
020 |
*/ |
021 |
setPlayerParameters : function(url) { |
022 |
try
{ |
023 |
if
(Player.object) { |
024 |
var
qt = Player.object; |
025 |
if
(!$.browser.msie && !qt.SetURL) { |
026 |
return
this; |
027 |
} |
028 |
qt.SetURL(url); |
029 |
qt.SetControllerVisible(false); |
030 |
qt.SetKioskMode(true); |
031 |
qt.SetVolume(100); |
032 |
qt.SetBgColor(‘#ffffff‘); |
033 |
} |
034 |
} catch
(e) { |
035 |
alert(‘resetPlayerParameters - ‘
+ e.toString()); |
036 |
} |
037 |
return
this; |
038 |
}, |
039 |
/** |
040 |
* 设置播放速率 |
041 |
|
042 |
* 实现实时播放 |
043 |
*/ |
044 |
setRate : function() { |
045 |
if
(Player.object) |
046 |
Player.object.SetRate(10); |
047 |
}, |
048 |
/** |
049 |
* 初始化播放路径,如:rtsp://192.168.0.100:554/3 |
050 |
* |
051 |
* @param stream |
052 |
* @returns |
053 |
*/ |
054 |
initGUrl : function(stream) { |
055 |
var
host = location.hostname; |
056 |
var
port = ‘‘;// ‘:‘+554; |
057 |
var
url = [ ‘rtsp://‘, host, port, ‘/‘, stream ].join(‘‘); |
058 |
return
url; |
059 |
}, |
060 |
/** |
061 |
* 注册事件,为IE浏览器注册时要多加个‘on‘在事件前面 |
062 |
*/ |
063 |
regQuickTimeEvents : function() { |
064 |
var
listerners = Player.listerners; |
065 |
if
(document.addEventListener) { |
066 |
var
obj = document.QT_EMB; |
067 |
if
(obj) { |
068 |
Player.object = obj; |
069 |
obj.addEventListener("qt_timechanged", |
070 |
listerners._qt_timechanged_listerner); |
071 |
obj.addEventListener("qt_stalled", |
072 |
listerners._qt_stalled_listerner); |
073 |
obj |
074 |
.addEventListener("qt_error", |
075 |
listerners._qt_error_listerner); |
076 |
} |
077 |
} else
{ |
078 |
var
obj = document.QT_OBJ; |
079 |
if
(obj) { |
080 |
Player.object = 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); |
086 |
} |
087 |
} |
088 |
return
this; |
089 |
}, |
090 |
listerners : { |
091 |
_qt_timechanged_listerner : function() { |
092 |
if
(Player.object) { |
093 |
var
qt = Player.object; |
094 |
if
(!$.browser.msie && !qt.SetRate) { |
095 |
return
false; |
096 |
} |
097 |
// 通过设置播放率快速播放来消耗缓存达到实时播放 |
098 |
qt.SetRate(10); |
099 |
qt.SetBgColor(‘#000000‘); |
100 |
Player.getStreamWidthHeight(qt, true); |
101 |
Player.adaptation(); |
102 |
} |
103 |
}, |
104 |
_qt_stalled_listerner : function() { |
105 |
alert(‘连接已终断,正在尝试重新连接...‘); |
106 |
}, |
107 |
_qt_error_listerner : function() { |
108 |
alert(‘播放时发生错误,请刷新页面或重新登录来解决此问题!‘); |
109 |
} |
110 |
}, |
111 |
/** |
112 |
* 将视频填充到当前播放器大小一致,并维持原始长宽比 |
113 |
|
114 |
* SetRectangle参数中每个值都必须是整形,不能有小数 在计算时可能出现高度或宽度相差一个像素 |
115 |
*/ |
116 |
adaptation : function() { |
117 |
try
{ |
118 |
if
(!Player.object) |
119 |
return
false; |
120 |
var
object = Player.object; |
121 |
var
qt = $(object); |
122 |
var
w_box = qt.width(); |
123 |
var
h_box = qt.height(); |
124 |
var
wh = Player.getStreamWidthHeight(object, false); |
125 |
if
(!wh) |
126 |
return
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; |
132 |
if
(dw == dh) { |
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); |
141 |
} else
{ |
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); |
147 |
} |
148 |
if
(!$.browser.msie && !object.SetRectangle) { |
149 |
return
false; |
150 |
} |
151 |
object.SetRectangle(rect.join(‘,‘)); |
152 |
} catch
(e) { |
153 |
// TODO |
154 |
} |
155 |
}, |
156 |
/** |
157 |
* 获取播放器对象的高度和宽度 |
158 |
* |
159 |
* @param playerObj |
160 |
* @param isInit |
161 |
* 是否将 Player.stream中的参数重写 |
162 |
* @returns |
163 |
*/ |
164 |
getStreamWidthHeight : function(playerObj, isFlash) { |
165 |
try
{ |
166 |
if
(!playerObj) |
167 |
return
false; |
168 |
if
(!$.browser.msie && !playerObj.GetRectangle) { |
169 |
return
false; |
170 |
} |
171 |
var
rect = playerObj.GetRectangle().split(‘,‘); |
172 |
var
width = parseInt(rect[2]) - parseInt(rect[0]); |
173 |
var
height = parseInt(rect[3]) - parseInt(rect[1]); |
174 |
if
(isFlash) { |
175 |
this.stream.width = width; |
176 |
this.stream.height = height; |
177 |
} |
178 |
return
{ |
179 |
width : width || this.stream.width, |
180 |
height : height || this.stream.height |
181 |
}; |
182 |
} catch
(e) { |
183 |
// TODO |
184 |
} |
185 |
}, |
186 |
/** |
187 |
* @param{Object} el 被放大对象 |
188 |
*/ |
189 |
requestFullScreen : function(el) { |
190 |
var
agent = ‘‘;// TODO 获取浏览器名称 |
191 |
var
obj = $(el); |
192 |
|
193 |
// 支持大多数浏览器全屏功能,除了FCK IE! |
194 |
var
requestMethod = el.requestFullScreen || el.webkitRequestFullScreen |
195 |
|| el.mozRequestFullScreen || el.msRequestFullScreen; |
196 |
|
197 |
if
(requestMethod) { |
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); |
203 |
|
204 |
// 根据不同浏览器作相应调整 |
205 |
if
(agent.name == ‘safari‘) { |
206 |
obj.offset({ |
207 |
top : 0, |
208 |
left : 0 |
209 |
}); |
210 |
} |
211 |
} else
{ |
212 |
// 如果浏览器没有全屏接口就放大显示区 |
213 |
// TODO |
214 |
} |
215 |
} |
216 |
}; |
代码说明:
1. 上述代码并不完整,需要根据实际情况作相应调整;
2.
基本使用方式:Player.regQuickTimeEvents().setPlayerParameters(url);
3.
Quicktime在播放RTSP时会有3-5秒延迟,这是缓存所至,但控件没有提供相应清空缓存方法,只有通过SetRate()来设置播放速率来清除缓存。
播放截图:
可能出现的问题:
1. 在显示/隐藏播放控件、全屏/恢复时会导致重新加载视频;
1. JavaScript Scripting Guide for QuickTime
2. QuickTime: Embed Tag Attributes
3. QuickTime fullscreen ( 很帅的东西)
| 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 |
使用Quicktime 实现视频直播(Live video using Quicktime) (转),布布扣,bubuko.com
使用Quicktime 实现视频直播(Live video using Quicktime) (转)
原文:http://www.cnblogs.com/hahaha22/p/3630796.html