player.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <template>
  2. <div id="dplayer" ref="dplayer" />
  3. </template>
  4. <script>
  5. import { videoUrl, submitPlayRecord } from '@/api/media/video'
  6. const hls = require('hls.js')
  7. const dashjs = require('dashjs')
  8. const flv = require('flv.js')
  9. const DPlayer = require('dplayer')
  10. export default {
  11. name: 'Play',
  12. props: {
  13. videoCover: {
  14. type: String,
  15. default: () => ''
  16. }
  17. },
  18. data() {
  19. return {
  20. hls,
  21. dashjs,
  22. flv,
  23. DPlayer,
  24. userId: 0,
  25. videoId: '',
  26. playRecord: null
  27. }
  28. },
  29. mounted() {
  30. const userInfo = this.$store.state.user.userInfo
  31. if (userInfo != null) {
  32. this.userId = userInfo.userId
  33. }
  34. this.videoId = this.$route.params.id
  35. videoUrl(this.$route.params.id)
  36. .then(res => {
  37. if (res.code === 0) {
  38. const urlType = res.data.type
  39. if (urlType === 'mp4') {
  40. const urls = res.data.urls
  41. for (const url of urls) {
  42. url.type = 'normal'
  43. }
  44. this.initMp4Player(this.userId, this.videoId, this.videoCover, urls)
  45. } else if (urlType === 'hls') {
  46. // this.initHlsPlayer(this.videoId, coverUrl, urls)
  47. } else if (urlType === 'dash') {
  48. // this.initDashPlayer(this.videoId, coverUrl, urls)
  49. } else if (urlType === 'flv') {
  50. // this.initFlvPlayer(this.videoId, coverUrl, urls)
  51. } else {
  52. console.log('无法识别 url 类型')
  53. }
  54. } else {
  55. console.error(res.msg)
  56. }
  57. }).catch(error => {
  58. console.error(error.message)
  59. })
  60. },
  61. methods: {
  62. // TODO 获取弹幕配置,将 videoUrl 作为本函数的回调
  63. danmakuConfig() {
  64. },
  65. submitVideoPlayRecord(currentTime) {
  66. if (this.playRecord == null) {
  67. return
  68. }
  69. this.playRecord.currentTime = currentTime
  70. submitPlayRecord(this.playRecord)
  71. .then(res => {
  72. if (res.code === 0) {
  73. console.log('播放进度已发送')
  74. } else {
  75. console.error(res.msg)
  76. }
  77. }).catch(error => {
  78. console.error(error.message)
  79. })
  80. },
  81. initMp4Player(userId, videoId, coverUrl, urls) {
  82. const player = new DPlayer({
  83. container: document.querySelector('#dplayer'),
  84. lang: 'zh-cn',
  85. logo: '/logo.png',
  86. autoplay: false,
  87. screenshot: false,
  88. video: {
  89. pic: coverUrl,
  90. defaultQuality: 0,
  91. quality: urls
  92. // url: videoUrl
  93. // type: 'auto',
  94. },
  95. danmaku: {
  96. id: videoId,
  97. maximum: 10000,
  98. api: '//api.reghao.cn/api/comment/danmaku/',
  99. token: 'bili',
  100. user: userId,
  101. bottom: '15%',
  102. unlimited: true
  103. }
  104. })
  105. if (userId !== 0) {
  106. console.log('初始化 playRecord')
  107. this.playRecord = {
  108. 'userId': this.userId,
  109. 'videoId': this.videoId,
  110. 'currentTime': 0.0
  111. }
  112. }
  113. // 跳转到指定秒
  114. // dp.seek(100)
  115. player.on('play', function() {
  116. console.log('mp4Player 开始播放事件' + this.userId)
  117. console.log(this.playRecord)
  118. if (this.playRecord == null) {
  119. return
  120. }
  121. this.playRecord.currentTime = player.video.currentTime
  122. submitPlayRecord(this.playRecord)
  123. .then(res => {
  124. }).catch(error => {
  125. console.error(error.message)
  126. })
  127. })
  128. player.on('pause', function() {
  129. if (this.playRecord == null) {
  130. return
  131. }
  132. this.playRecord.currentTime = player.video.currentTime
  133. submitPlayRecord(this.playRecord)
  134. .then(res => {
  135. }).catch(error => {
  136. console.error(error.message)
  137. })
  138. })
  139. player.on('ended', function() {
  140. // TODO 当前视频播放完成后判断是否继续播放相关推荐中的视频
  141. if (this.playRecord == null) {
  142. return
  143. }
  144. this.playRecord.currentTime = player.video.currentTime
  145. submitPlayRecord(this.playRecord)
  146. .then(res => {
  147. }).catch(error => {
  148. console.error(error.message)
  149. })
  150. })
  151. player.on('seeking', function() {
  152. if (this.playRecord == null) {
  153. return
  154. }
  155. this.playRecord.currentTime = player.video.currentTime
  156. submitPlayRecord(this.playRecord)
  157. .then(res => {
  158. }).catch(error => {
  159. console.error(error.message)
  160. })
  161. })
  162. player.on('seeked', function() {
  163. if (this.playRecord == null) {
  164. return
  165. }
  166. this.playRecord.currentTime = player.video.currentTime
  167. submitPlayRecord(this.playRecord)
  168. .then(res => {
  169. }).catch(error => {
  170. console.error(error.message)
  171. })
  172. })
  173. var i = 0
  174. player.on('progress', function() {
  175. console.log('i = ' + i)
  176. if (i % 5 === 0) {
  177. if (this.playRecord == null) {
  178. return
  179. }
  180. this.playRecord.currentTime = player.video.currentTime
  181. submitPlayRecord(this.playRecord)
  182. .then(res => {
  183. }).catch(error => {
  184. console.error(error.message)
  185. })
  186. }
  187. i++
  188. })
  189. },
  190. initHlsPlayer(videoId, coverUrl, videoUrl) {
  191. const player = new DPlayer({
  192. container: document.querySelector('#dplayer'),
  193. lang: 'zh-cn',
  194. autoplay: false,
  195. screenshot: true,
  196. video: {
  197. pic: coverUrl,
  198. url: videoUrl,
  199. type: 'hls'
  200. },
  201. logo: '/logo.png',
  202. danmaku: {
  203. id: videoId,
  204. maximum: 10000,
  205. api: '//api.reghao.cn/api/media/danmaku/',
  206. token: 'bili',
  207. user: this.userId,
  208. videoId: videoId,
  209. bottom: '15%',
  210. unlimited: true
  211. }
  212. })
  213. player.on('play', function() {
  214. if (this.playRecord == null) {
  215. return
  216. }
  217. this.playRecord.currentTime = player.video.currentTime
  218. submitPlayRecord(this.playRecord)
  219. .then(res => {
  220. }).catch(error => {
  221. console.error(error.message)
  222. })
  223. })
  224. player.on('pause', function() {
  225. if (this.playRecord == null) {
  226. return
  227. }
  228. this.playRecord.currentTime = player.video.currentTime
  229. submitPlayRecord(this.playRecord)
  230. .then(res => {
  231. }).catch(error => {
  232. console.error(error.message)
  233. })
  234. })
  235. player.on('ended', function() {
  236. // TODO 当前视频播放完成后判断是否继续播放相关推荐中的视频
  237. if (this.playRecord == null) {
  238. return
  239. }
  240. this.playRecord.currentTime = player.video.currentTime
  241. submitPlayRecord(this.playRecord)
  242. .then(res => {
  243. }).catch(error => {
  244. console.error(error.message)
  245. })
  246. })
  247. player.on('seeking', function() {
  248. if (this.playRecord == null) {
  249. return
  250. }
  251. this.playRecord.currentTime = player.video.currentTime
  252. submitPlayRecord(this.playRecord)
  253. .then(res => {
  254. }).catch(error => {
  255. console.error(error.message)
  256. })
  257. })
  258. player.on('seeked', function() {
  259. if (this.playRecord == null) {
  260. return
  261. }
  262. this.playRecord.currentTime = player.video.currentTime
  263. submitPlayRecord(this.playRecord)
  264. .then(res => {
  265. }).catch(error => {
  266. console.error(error.message)
  267. })
  268. })
  269. var i = 0
  270. player.on('progress', function() {
  271. console.log('i = ' + i)
  272. if (i % 5 === 0) {
  273. if (this.playRecord == null) {
  274. return
  275. }
  276. this.playRecord.currentTime = player.video.currentTime
  277. submitPlayRecord(this.playRecord)
  278. .then(res => {
  279. }).catch(error => {
  280. console.error(error.message)
  281. })
  282. }
  283. i++
  284. })
  285. },
  286. initDashPlayer(videoId, coverUrl, videoUrl) {
  287. console.log('初始化 dash 播放器')
  288. const player = new DPlayer({
  289. container: document.getElementById('dplayer'),
  290. video: {
  291. url: videoUrl,
  292. type: 'dash'
  293. }
  294. })
  295. console.log('dash 播放器初始化完成')
  296. player.on('play', function() {
  297. if (this.playRecord == null) {
  298. return
  299. }
  300. this.playRecord.currentTime = player.video.currentTime
  301. submitPlayRecord(this.playRecord)
  302. .then(res => {
  303. }).catch(error => {
  304. console.error(error.message)
  305. })
  306. })
  307. },
  308. initFlvPlayer(videoId, coverUrl, videoUrl) {
  309. console.log('初始化 flv 播放器')
  310. const dp = new DPlayer({
  311. container: document.getElementById('dplayer'),
  312. video: {
  313. url: videoUrl,
  314. type: 'flv'
  315. },
  316. pluginOptions: {
  317. flv: {
  318. // refer to https://github.com/bilibili/flv.js/blob/master/docs/api.md#flvjscreateplayer
  319. mediaDataSource: {
  320. // mediaDataSource config
  321. },
  322. config: {
  323. // config
  324. }
  325. }
  326. }
  327. })
  328. console.log(dp.plugins.flv) // flv 实例
  329. }
  330. }
  331. }
  332. </script>
  333. <style>
  334. #dplayer {
  335. height: 500px;
  336. }
  337. </style>