player.vue 9.0 KB

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