WSPlayer.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import CONSTANT from './CONSTANT.js'
  2. import RealPlayerItem from './RealPlayer.js'
  3. import RecordPlayerItem from './RecordPlayer.js'
  4. /* ---------------- WSPlayer ---------------- */
  5. const defaultConfig = {
  6. num: 4,
  7. showControl: true,
  8. type: 'real'
  9. }
  10. class WSPlayer {
  11. /**
  12. * 构造函数
  13. * @param {String} options.el 必传 播放器domId
  14. * @param {String} options.type 必传 类型 real | record
  15. * @param {Sting} options.serverIp 必传 服务器IP
  16. * @param {number} options.num 播放器数量 default 1
  17. * @param {boolean} options.showControl 显示播放器控制栏 default false
  18. */
  19. constructor(options) {
  20. if (!options.el || !options.type || !options.serverIp) {
  21. console.error(`el, type, serverIp 为必传参数,请校验入参`)
  22. return false
  23. }
  24. let isHttps = location.protocol == 'https:'
  25. // 协议判断
  26. this.protocol = isHttps ? 'wss' : 'ws'
  27. // 服务器IP
  28. this.serverIp = options.serverIp ? options.serverIp : location.hostname
  29. this.options = Object.assign({}, defaultConfig, options)
  30. this.$el = $('#' + options.el)
  31. this.width = this.$el.attr('width')
  32. this.height = this.$el.attr('height')
  33. this.$el.height(`${this.height}px`)
  34. this.$el.width(`${this.width}px`)
  35. console.log(this.$el.width())
  36. this.$el.addClass(`ws-player`)
  37. // 添加player-wrapper
  38. this.$el.append(`<div class="player-wrapper"></div>`)
  39. this.$wrapper = $('.player-wrapper', this.$el)
  40. this.playerList = []
  41. $(this.$el).attr('inited', true)
  42. switch (options.type) {
  43. case 'real':
  44. this.wsPort = CONSTANT.websocketPorts.realmonitor[this.protocol]
  45. if (this.options.showControl) {
  46. this.__addRealControl()
  47. } else {
  48. this.$wrapper.addClass('nocontrol')
  49. }
  50. for (let i of [0, 1, 2, 3]) {
  51. this.playerList.push(new RealPlayerItem({
  52. wrapperDomId: options.el,
  53. index: i,
  54. wsPlayer: this
  55. }))
  56. }
  57. break;
  58. case 'record':
  59. for (let i of [0, 1, 2, 3]) {
  60. this.playerList.push(new RecordPlayerItem({
  61. wrapperDomId: options.el,
  62. index: i,
  63. wsPlayer: this
  64. }))
  65. }
  66. this.wsPort = CONSTANT.websocketPorts.playback[this.protocol]
  67. if (this.options.showControl) {
  68. this.__addRecordControl()
  69. } else {
  70. this.$wrapper.addClass('nocontrol')
  71. }
  72. break;
  73. default:
  74. break;
  75. }
  76. // 设置服务器websocektUrl地址
  77. this.wsURL = `${this.protocol}://${this.serverIp}:${this.wsPort}`
  78. this.setSelectIndex(0)
  79. this.setPlayerNum(options.num)
  80. }
  81. /**
  82. * 播放实时视频
  83. * @param {*} options.rtspURL String | array
  84. * @param {*} options.decodeMode 可选参数 video | canvas
  85. * @param {*} options.wsURL 可选参数
  86. */
  87. playReal(opt) {
  88. if (!opt.rtspURL) {
  89. console.error("播放实时视频需要传入rtspURL")
  90. return
  91. }
  92. // 多个rtsp地址时,按照播放器顺序,选择播放器进行播放
  93. if (opt.rtspURL instanceof Array) {
  94. opt.rtspURL.forEach((item, i) => {
  95. if (i < 4) {
  96. this.playReal(Object.assign({}, opt, {
  97. rtspURL: item
  98. }))
  99. }
  100. })
  101. } else {
  102. let player = this.playerList[this.selectIndex]
  103. if (this.showNum > 1) {
  104. this.setSelectIndex((this.selectIndex + 1) % this.showNum)
  105. }
  106. player.init(opt)
  107. }
  108. }
  109. /**
  110. * 播放录像
  111. * @param {String} options.decodeMode 可选参数 video | canvas
  112. * @param {String} options.wsURL 可选参数
  113. * @param {Function} options.recordSource 2=设备,3=中心
  114. * recordSource == 2 设备录像,按照时间方式播放
  115. * @param {String} options.rtspURL String
  116. * @param {Number | String} options.startTime 开始时间 时间戳或者'2021-09-18 15:40:00'格式的时间字符串
  117. * @param {Number | String} options.endTime 结束时间 时间戳或者'2021-09-18 15:40:00'格式的时间字符串
  118. * @param {Function} options.reload 重新拉流的回调函数,用于时间回放,返回promise
  119. * reload(newStarTime, endTime).then(newRtspUrl => { play continue})
  120. * recordSource == 3 中心录像,按照文件方式播放
  121. * @param {Function} options.RecordFiles 文件列表
  122. * @param {Function} options.getRtsp 文件列表
  123. * getRtsp(file).then(newRtspUrl => { play continue})
  124. */
  125. playRecord(opt) {
  126. let player = this.playerList[this.selectIndex]
  127. if (this.showNum > 1) {
  128. this.setSelectIndex((this.selectIndex + 1) % this.showNum)
  129. }
  130. player.init(opt)
  131. }
  132. /**
  133. * 播放
  134. */
  135. play() {
  136. let player = this.playerList[this.selectIndex]
  137. player.play()
  138. }
  139. /**
  140. * 暂停播放
  141. */
  142. pause() {
  143. let player = this.playerList[this.selectIndex]
  144. player.pause()
  145. }
  146. /**
  147. * 倍速播放
  148. * @param {Number} speed 倍速
  149. */
  150. playSpeed(speed) {
  151. if (this.options.type === 'real') {
  152. console.warn('实时预览不支持倍速播放')
  153. return
  154. }
  155. let player = this.playerList[this.selectIndex]
  156. player.playSpeed(speed)
  157. }
  158. /**
  159. * 时间跳转
  160. * @param {*} time
  161. */
  162. playByTime(time) {
  163. if (this.options.type === 'real') {
  164. console.warn('实时预览不支持时间设置')
  165. return
  166. }
  167. let player = this.playerList[this.selectIndex]
  168. player.playByTime(time)
  169. }
  170. /**
  171. * 设置选中的播放器
  172. * @param {*} index
  173. */
  174. setSelectIndex(index) {
  175. this.selectIndex = index
  176. this.playerList.forEach((item, i) => {
  177. if (i === index) {
  178. item.$el.removeClass('unselected').addClass('selected')
  179. } else {
  180. item.$el.removeClass('selected').addClass('unselected')
  181. }
  182. })
  183. }
  184. /**
  185. * 控制视频播放器数量
  186. * @param {*} number
  187. * @param {*} index
  188. */
  189. setPlayerNum(number, index) {
  190. console.log("WSPlayer setPlayerNum", number, index)
  191. this.showNum = number
  192. switch (number) {
  193. case 1:
  194. this.$wrapper.addClass('fullplayer')
  195. break;
  196. default:
  197. this.$wrapper.removeClass('fullplayer')
  198. break;
  199. }
  200. }
  201. // 关闭所有播放器
  202. close() {
  203. this.playerList.forEach(item => {
  204. item.close()
  205. })
  206. }
  207. /* ----------------------- 内部方法 -----------------------*/
  208. /**
  209. * 添加实时播放控制栏
  210. */
  211. __addRealControl() {
  212. this.$el.append(`
  213. <div class="ws-control">
  214. <div class="flex">
  215. <div class="ws-ctrl-icon one-screen-icon"></div>
  216. <div class="ws-ctrl-icon four-screen-icon"></div>
  217. </div>
  218. </div>
  219. `)
  220. $('.one-screen-icon', this.$el).click(() => {
  221. this.setPlayerNum(1, this.selectIndex)
  222. })
  223. $('.four-screen-icon', this.$el).click(() => {
  224. this.setPlayerNum(4)
  225. })
  226. }
  227. /**
  228. * 添加录像回放控制栏
  229. */
  230. __addRecordControl() {
  231. this.$el.append(`
  232. <div class="ws-control">
  233. <div class="flex">
  234. <div class="ws-ctrl-icon one-screen-icon"></div>
  235. <div class="ws-ctrl-icon four-screen-icon"></div>
  236. </div>
  237. </div>
  238. `)
  239. $('.one-screen-icon', this.$el).click(() => {
  240. this.setPlayerNum(1, this.selectIndex)
  241. })
  242. $('.four-screen-icon', this.$el).click(() => {
  243. this.setPlayerNum(4)
  244. })
  245. }
  246. }
  247. export default WSPlayer