11<!DOCTYPE html>
22< html lang ="en ">
3- < head >
4- < meta charset ="UTF-8 " />
5- < meta
6- name ="viewport "
7- content ="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0 "
8- />
9- < title > Document</ title >
10- < script src ="./ezuikit.js "> </ script >
11- </ head >
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > multi(多屏)</ title >
7+ < script src ="./ezuikit.js "> </ script >
8+ < style >
9+ .multi-container {
10+ display : flex;
11+ }
12+ .main-container {
13+ width : 600px ;
14+ height : 606px ;
15+ background-color : # 000 ;
16+ }
1217
13- < body >
14- < div className ="demo ">
15- < h2 > 视频模式使用示例:</ h2 >
16- < div >
17- < div id ="video-container " style ="width: 600px "> </ div >
18+ # main {
19+ width : 600px ;
20+ height : 606px ;
21+ }
22+
23+ .right-container {
24+ display : flex;
25+ flex-direction : column;
26+ }
27+ .right-container > div {
28+ background-color : # 000 ;
29+ border : 1px solid transparent;
30+ position : relative;
31+ }
32+
33+ .sub-container img {
34+ position : absolute;
35+ top : 0 ;
36+ left : 0 ;
37+ right : 0 ;
38+ bottom : 0 ;
39+ width : 100% ;
40+ height : 100% ;
41+ font-size : 0 ;
42+ outline : none;
43+ }
44+
45+ # right1 , # right2 , # right3 {
46+ width : 300px ;
47+ height : 200px ;
48+ }
49+
50+ .selected {
51+ border-color : red!important ;
52+ }
53+ </ style >
54+ </ head >
55+ < body >
56+ < div class ="multi-container ">
57+ < div class ="main-container ">
58+ < div id ="main "> </ div >
59+ </ div >
60+ < div class ="right-container ">
61+ < div class ="sub-container selected ">
62+ < div id ="right1 "> </ div >
1863 </ div >
19- < div >
20- < div id ="video-container2 " style =" width: 600px "> </ div >
64+ < div class =" sub-container " >
65+ < div id ="right2 "> </ div >
2166 </ div >
22- < div >
23- < button onClick ="play() "> play</ button >
24- < button onClick ="stop() "> stop</ button >
25- < button onClick ="getOSDTime() "> getOSDTime</ button >
26- < button onClick ="getOSDTime2() "> getOSDTime2</ button >
27- < button onClick ="capturePicture() "> capturePicture</ button >
28- < button onClick ="openSound() "> openSound</ button >
29- < button onClick ="closeSound() "> closeSound</ button >
30- < button onClick ="startSave() "> startSave</ button >
31- < button onClick ="stopSave() "> stopSave</ button >
32- < button onClick ="ezopenStartTalk() "> 开始对讲</ button >
33- < button onClick ="ezopenStopTalk() "> 结束对讲</ button >
34- < button onClick ="fullScreen() "> 全屏</ button >
67+ < div class ="sub-container ">
68+ < div id ="right3 "> </ div >
3569 </ div >
3670 </ div >
37- < script >
38- var player ;
39- var player2 ;
40- fetch ( "https://open.ys7.com/jssdk/ezopen/demo/token" )
41- . then ( ( response ) => response . json ( ) )
42- . then ( ( res ) => {
43- var accessToken = res . data . accessToken ;
44- player = new EZUIKit . EZUIKitPlayer ( {
45- id : "video-container" , // 视频容器ID
46- accessToken : accessToken ,
47- url : "ezopen://open.ys7.com/G39444019/1.live" ,
48- template : "pcLive" , // simple - 极简版;standard-标准版;security - 安防版(预览回放);voice-语音版; theme-可配置主题;
49- plugin : [ "talk" ] , // 加载插件,talk-对讲
50- width : 600 ,
51- height : 400 ,
52- env : {
53- // https://open.ys7.com/help/1772?h=domain
54- // domain默认是 https://open.ys7.com, 如果是私有化部署或海外的环境,请配置对应的domain
55- // The default domain is https://open.ys7.com If it is a private deployment or overseas (outside of China) environment, please configure the corresponding domain
56- domain : "https://open.ys7.com" ,
71+ </ div >
72+ < script >
73+ ( function ( ) {
74+ // 一个主屏(选中的展示其中),三个副屏, 副屏点击切换展示在主屏中, 选中的副屏展示切换前的截图当作封面
75+
76+ let players = [ ]
77+ let mainPlayer = null
78+ let cover = document . createElement ( 'img' )
79+ let arr = [
80+ {
81+ url : "ezopen://open.ys7.com/BC7799090/1.hd.live" ,
82+ id : "right1" ,
83+ accessToken : "at.ao9rmhn824rnxeao5ck7fm4e1j2x7zey-4g4qudp8vd-1vumcfo-t28imym6"
84+ } ,
85+ {
86+ url : "ezopen://open.ys7.com/BF6985118/1.hd.live" ,
87+ id : "right2" ,
88+ accessToken : "at.ao9rmhn824rnxeao5ck7fm4e1j2x7zey-4g4qudp8vd-1vumcfo-t28imym6"
89+ } ,
90+ {
91+ url : "ezopen://open.ys7.com/C69625509/1.hd.live" ,
92+ id : "right3" ,
93+ accessToken : "at.ao9rmhn824rnxeao5ck7fm4e1j2x7zey-4g4qudp8vd-1vumcfo-t28imym6"
94+ } ,
95+ ]
96+ let selectedIndex = 0
97+
98+ function createPlayer ( options ) {
99+ return new EZUIKit . EZUIKitPlayer ( {
100+ ...options ,
101+ template : "simple" , // simple: 极简版; pcLive: 预览; pcRec: 回放; security: 安防版; voice: 语音版;
102+ // plugin: ["talk"], // 加载插件,talk-对讲
103+ language : "en" , // zh | en
104+ // debugDownloadData: true,
105+ handleError : ( error ) => {
106+ console . error ( "handleError" , error ) ;
57107 } ,
58- } ) ;
59- player2 = new EZUIKit . EZUIKitPlayer ( {
60- id : "video-container2" , // 视频容器ID
61- accessToken :
62- "at.e0mnhu50d7bwohb40358mchq13aobjm2-6m2v78jd7m-1g22scv-lcn0rdqm1" ,
63- url : "ezopen://open.ys7.com/G39444019/1.live" ,
64- template : "pcLive" , // simple - 极简版;standard-标准版;security - 安防版(预览回放);voice-语音版; theme-可配置主题;
65- plugin : [ "talk" ] , // 加载插件,talk-对讲
66- width : 600 ,
67- height : 400 ,
108+ download : false ,
68109 env : {
69110 // https://open.ys7.com/help/1772?h=domain
70111 // domain默认是 https://open.ys7.com, 如果是私有化部署或海外的环境,请配置对应的domain
71112 // The default domain is https://open.ys7.com If it is a private deployment or overseas (outside of China) environment, please configure the corresponding domain
72113 domain : "https://open.ys7.com" ,
73114 } ,
74- } ) ;
75- } ) ;
76- function fullScreen ( ) {
77- var playPromise = player . fullScreen ( ) ;
78- playPromise . then ( ( data ) => {
79- console . log ( "promise 获取 数据" , data ) ;
80- } ) ;
81- }
82- function play ( ) {
83- var playPromise = player . play ( ) ;
84- playPromise . then ( ( data ) => {
85- console . log ( "promise 获取 数据" , data ) ;
86- } ) ;
87- }
88- function stop ( ) {
89- var stopPromise = player . stop ( ) ;
90- stopPromise . then ( ( data ) => {
91- console . log ( "promise 获取 数据" , data ) ;
92- } ) ;
93- }
94- function getOSDTime ( ) {
95- var getOSDTimePromise = player . getOSDTime ( ) ;
96- getOSDTimePromise . then ( ( data ) => {
97- console . log ( "promise 获取 数据" , data ) ;
98- } ) ;
99- }
100- function getOSDTime2 ( ) {
101- var getOSDTimePromise = player2 . getOSDTime ( ) ;
102- getOSDTimePromise . then ( ( data ) => {
103- console . log ( "promise 获取 数据" , data ) ;
104- } ) ;
105- }
106- function capturePicture ( ) {
107- var capturePicturePromise = player . capturePicture ( ) ;
108- capturePicturePromise . then ( ( data ) => {
109- console . log ( "promise 获取 数据" , data ) ;
110- } ) ;
111- }
112- function openSound ( ) {
113- var openSoundPromise = player . openSound ( ) ;
114- openSoundPromise . then ( ( data ) => {
115- console . log ( "promise 获取 数据" , data ) ;
116- } ) ;
117- }
118- function closeSound ( ) {
119- var closeSoundPromise = player . closeSound ( ) ;
120- closeSoundPromise . then ( ( data ) => {
121- console . log ( "promise 获取 数据" , data ) ;
122- } ) ;
123- }
124- function startSave ( ) {
125- var startSavePromise = player . startSave ( ) ;
126- startSavePromise . then ( ( data ) => {
127- console . log ( "promise 获取 数据" , data ) ;
128- } ) ;
129- }
130- function stopSave ( ) {
131- var stopSavePromise = player . stopSave ( ) ;
132- stopSavePromise . then ( ( data ) => {
133- console . log ( "promise 获取 数据" , data ) ;
134- } ) ;
115+ // 日志打印设置
116+ loggerOptions : {
117+ // player.setLoggerOptions(options)
118+ level : "ERROR" , // INFO LOG WARN ERROR
119+ name : "ezuikit" ,
120+ showTime : true ,
121+ } ,
122+ // 视频流的信息回调类型
123+ /**
124+ * 打开流信息回调,监听 streamInfoCB 事件
125+ * 0 : 每次都回调
126+ * 1 : 只回调一次
127+ * 注意:会影响性能
128+ * 默认值 1
129+ */
130+ streamInfoCBType : 1 ,
131+ staticPath : "/ezuikit_static" , // 如果想使用本地静态资源,请复制根目录下ezuikit_static 到当前目录下, 然后设置该值
132+ // v8.1.10
133+ // 自定义清晰度 默认 null, 如果有值 sdk 内部不在进行获取, null 默认使用接口获取的清晰度列表, videoLevelList.length === 0 不展示清晰度控件 sdk 内部不在进行获取, videoLevelList.length > 0 展示控件 sdk 内部不在进行获取
134+ // videoLevelList: [
135+ // { level: 0, name: "流畅", streamTypeIn: 1 },
136+ // { level: 1, name: "标清", streamTypeIn: 1 },
137+ // ],
138+ } )
135139 }
136- function ezopenStartTalk ( ) {
137- player . startTalk ( ) ;
140+
141+ for ( let i = 0 ; i < arr . length ; i ++ ) {
142+ if ( selectedIndex === i ) {
143+ players . push ( null )
144+ continue
145+ }
146+ players . push ( createPlayer ( arr [ i ] ) )
138147 }
139- function ezopenStopTalk ( ) {
140- player . stopTalk ( ) ;
148+
149+ mainPlayer = createPlayer ( {
150+ ...arr [ selectedIndex ] ,
151+ id : "main"
152+ } )
153+
154+ mainPlayer . eventEmitter . on ( EZUIKit . EZUIKitPlayer . EVENTS . firstFrameDisplay , ( ) => {
155+ setTimeout ( ( ) => {
156+ mainPlayer . capturePicture ( ) . then ( res => {
157+ Array . from ( document . querySelectorAll ( ".sub-container" ) ) [ selectedIndex ] . appendChild ( cover )
158+ cover . src = res . data . base64
159+ } )
160+ } , 10 )
161+ } )
162+
163+ function setSelectedIndex ( index ) {
164+ const listEle = Array . from ( document . querySelectorAll ( ".sub-container" ) )
165+
166+ if ( players [ index ] ) {
167+ // 记录上一次选中下标, 因为 capturePicture 时异步操作,所以需要记录
168+ const preIndex = selectedIndex
169+ // 销毁选中节点
170+ players [ index ] . capturePicture ( ) . then ( res => {
171+ listEle [ preIndex ] . removeChild ( cover )
172+ listEle [ preIndex ] . classList . remove ( "selected" )
173+ listEle [ index ] . appendChild ( cover )
174+ cover . src = res . data . base64
175+
176+ // FIXME: 其实这里平移窗口,然后 resize 窗口应该更合理, 不用每次都销毁重新创建
177+ players [ index ] . destroy ( )
178+ players [ index ] = null
179+ } )
180+ // 销毁主屏
181+ if ( mainPlayer ) {
182+ mainPlayer . destroy ( )
183+ mainPlayer = null
184+ }
185+ mainPlayer = createPlayer ( {
186+ ...arr [ index ] ,
187+ id : "main"
188+ } )
189+ } else {
190+ return
191+ }
192+
193+ players [ selectedIndex ] = createPlayer ( {
194+ ...arr [ selectedIndex ] ,
195+ } )
196+ selectedIndex = index
197+ listEle [ selectedIndex ] . classList . add ( "selected" )
141198 }
142- </ script >
143- </ body >
144- </ html >
199+
200+ Array . from ( document . querySelectorAll ( ".sub-container" ) ) . map ( ( ele , i ) => {
201+ ele . addEventListener ( "click" , ( e ) => {
202+ setSelectedIndex ( i )
203+ } )
204+ } )
205+ } ) ( ) ;
206+ </ script >
207+ </ body >
208+ </ html >
0 commit comments