reghao пре 4 година
родитељ
комит
89c5d2da07

+ 7 - 1
src/api/media/video.js

@@ -8,7 +8,8 @@ const videoApi = {
   videoCategoryApi: '/api/media/video/category',
   videoPostSubmitApi: '/api/media/video/submit',
   keywordSuggestApi: '/api/media/video/search/suggest',
-  videoSearchApi: '/api/media/video/search/query'
+  videoSearchApi: '/api/media/video/search/query',
+  playerRecordApi: '/api/media/video/play/record'
 }
 
 // 视频推荐接口
@@ -49,3 +50,8 @@ export function keywordSuggest(keyword) {
 export function videoQuery(keyword) {
   return $axios.get(videoApi.videoSearchApi + '?keyword=' + keyword)
 }
+
+// 播放记录
+export function submitPlayRecord(playerRecord) {
+  return $axios.post(videoApi.playerRecordApi, playerRecord)
+}

+ 1 - 1
src/components/player/live.vue → src/components/player/live-player.vue

@@ -13,7 +13,7 @@
 import { videoUrl } from '@/api/media/video'
 const flvjs = require('flv.js')
 export default {
-  name: 'Live',
+  name: 'LivePlayer',
   data() {
     return {
       flvjs,

+ 184 - 46
src/components/player/player.vue

@@ -3,7 +3,7 @@
 </template>
 
 <script>
-import { videoUrl } from '@/api/media/video'
+import { videoUrl, submitPlayRecord } from '@/api/media/video'
 const hls = require('hls.js')
 const dashjs = require('dashjs')
 const flv = require('flv.js')
@@ -16,6 +16,7 @@ export default {
       dashjs,
       flv,
       DPlayer,
+      userId: 0,
       videoId: ''
     }
   },
@@ -24,50 +25,45 @@ export default {
     if (userInfo != null) {
       this.userId = userInfo.id.toString()
     } else {
-      this.userId = 111222333
+      this.userId = 110101
     }
-
     this.videoId = this.$route.params.id
-    this.getVideoUrl(this.videoId)
+    videoUrl(this.$route.params.id)
+      .then(res => {
+        if (res.code === 0) {
+          // TODO 返回一个 dplayer 播放器对象,包含一些常用的属性
+          var coverUrl = res.data.coverUrl
+          var videoUrl = res.data.videoUrl
+          var urlType = res.data.urlType
+          if (urlType === 'mp4') {
+            this.initMp4Player(this.videoId, coverUrl, videoUrl)
+          } else if (urlType === 'hls') {
+            this.initHlsPlayer(this.videoId, coverUrl, videoUrl)
+          } else if (urlType === 'dash') {
+            this.initDashPlayer(this.videoId, coverUrl, videoUrl)
+          } else if (urlType === 'flv') {
+            this.initFlvPlayer(this.videoId, coverUrl, videoUrl)
+          } else {
+            console.log('无法识别 url 类型')
+          }
+        } else {
+          this.$notify({
+            title: res.code,
+            message: res.msg,
+            type: 'warning',
+            duration: 500
+          })
+        }
+      })
+      .catch(error => {
+        console.error(error.message)
+      })
   },
   methods: {
     // TODO 获取弹幕配置,将 videoUrl 作为本函数的回调
     danmakuConfig() {
     },
-    getVideoUrl(videoId) {
-      videoUrl(videoId)
-        .then(res => {
-          if (res.code === 0) {
-            // TODO 返回一个 dplayer 播放器对象,包含一些常用的属性
-            var coverUrl = res.data.coverUrl
-            var videoUrl = res.data.videoUrl
-            var urlType = res.data.urlType
-            if (urlType === 'mp4') {
-              this.initMp4Player(this.videoId, coverUrl, videoUrl)
-            } else if (urlType === 'hls') {
-              this.initHlsPlayer(this.videoId, coverUrl, videoUrl)
-            } else if (urlType === 'dash') {
-              this.initDashPlayer(this.videoId, coverUrl, videoUrl)
-            } else if (urlType === 'flv') {
-              this.initFlvPlayer(this.videoId, coverUrl, videoUrl)
-            } else {
-              console.log('无法识别 url 类型')
-            }
-          } else {
-            this.$notify({
-              title: res.code,
-              message: res.msg,
-              type: 'warning',
-              duration: 500
-            })
-          }
-        })
-        .catch(error => {
-          console.error(error.message)
-        })
-    },
     initMp4Player(videoId, coverUrl, videoUrl) {
-      const vidId = videoId
       const player = new DPlayer({
         container: document.querySelector('#dplayer'),
         lang: 'zh-cn',
@@ -83,7 +79,7 @@ export default {
         danmaku: {
           id: videoId,
           maximum: 10000,
-          api: '/api/media/danmaku/',
+          api: 'api.reghao.cn/api/media/danmaku/',
           token: 'hertube',
           user: this.userId,
           bottom: '15%',
@@ -95,24 +91,24 @@ export default {
       // dp.seek(100)
 
       player.on('play', function() {
-        console.log(vidId + ' 播放开始' + player.video.currentTime)
+        console.log(videoId + ' 播放开始' + player.video.currentTime)
       })
 
       player.on('pause', function() {
-        console.log(vidId + ' 播放暂停' + player.video.currentTime)
+        console.log(videoId + ' 播放暂停' + player.video.currentTime)
       })
 
       player.on('ended', function() {
         // TODO 当前视频播放完成后判断是否继续播放相关推荐中的视频
-        console.log(vidId + ' 播放结束' + player.video.currentTime)
+        console.log(videoId + ' 播放结束' + player.video.currentTime)
       })
 
       player.on('seeking', function() {
-        console.log(vidId + ' seeking 事件 ' + player.video.currentTime)
+        console.log(videoId + ' seeking 事件 ' + player.video.currentTime)
       })
 
       player.on('seeked', function() {
-        console.log(vidId + ' seeked 事件' + player.video.currentTime)
+        console.log(videoId + ' seeked 事件' + player.video.currentTime)
       })
 
       const interval = 5
@@ -121,13 +117,13 @@ export default {
         console.log('i = ' + i)
         if (i % interval === 0) {
           // TODO 每 5s 向后端报告一次播放进度
-          console.log(vidId + ' 播放进度 ' + player.video.currentTime)
+          console.log(videoId + ' 播放进度 ' + player.video.currentTime)
         }
         i++
       })
     },
     initHlsPlayer(videoId, coverUrl, videoUrl) {
-      new DPlayer({
+      const player = new DPlayer({
         container: document.querySelector('#dplayer'),
         lang: 'zh-cn',
         autoplay: false,
@@ -137,7 +133,149 @@ export default {
           url: videoUrl,
           type: 'hls'
         },
-        logo: '/logo.png'
+        logo: '/logo.png',
+        danmaku: {
+          id: videoId,
+          maximum: 10000,
+          api: '//api.reghao.cn/api/media/danmaku/',
+          token: 'hertube',
+          user: this.userId,
+          bottom: '15%',
+          unlimited: true
+        }
+      })
+
+      const playRecord1 = {
+        'userId': 110110,
+        'videoId': videoId,
+        'currentTime': 0.0
+      }
+
+      player.on('play', function() {
+        playRecord1.currentTime = player.video.currentTime
+        submitPlayRecord(playRecord1)
+          .then(res => {
+            // eslint-disable-next-line no-empty
+            if (res.code === 0) {
+            } else {
+              this.$notify({
+                title: res.code,
+                message: res.msg,
+                type: 'warning',
+                duration: 500
+              })
+            }
+          })
+          .catch(error => {
+            console.error(error.message)
+          })
+      })
+
+      player.on('pause', function() {
+        playRecord1.currentTime = player.video.currentTime
+        submitPlayRecord(playRecord1)
+          .then(res => {
+            // eslint-disable-next-line no-empty
+            if (res.code === 0) {
+            } else {
+              this.$notify({
+                title: res.code,
+                message: res.msg,
+                type: 'warning',
+                duration: 500
+              })
+            }
+          })
+          .catch(error => {
+            console.error(error.message)
+          })
+      })
+
+      player.on('ended', function() {
+        // TODO 当前视频播放完成后判断是否继续播放相关推荐中的视频
+        playRecord1.currentTime = player.video.currentTime
+        submitPlayRecord(playRecord1)
+          .then(res => {
+            // eslint-disable-next-line no-empty
+            if (res.code === 0) {
+            } else {
+              this.$notify({
+                title: res.code,
+                message: res.msg,
+                type: 'warning',
+                duration: 500
+              })
+            }
+          })
+          .catch(error => {
+            console.error(error.message)
+          })
+      })
+
+      player.on('seeking', function() {
+        playRecord1.currentTime = player.video.currentTime
+        submitPlayRecord(playRecord1)
+          .then(res => {
+            // eslint-disable-next-line no-empty
+            if (res.code === 0) {
+            } else {
+              this.$notify({
+                title: res.code,
+                message: res.msg,
+                type: 'warning',
+                duration: 500
+              })
+            }
+          })
+          .catch(error => {
+            console.error(error.message)
+          })
+      })
+
+      player.on('seeked', function() {
+        playRecord1.currentTime = player.video.currentTime
+        submitPlayRecord(playRecord1)
+          .then(res => {
+            // eslint-disable-next-line no-empty
+            if (res.code === 0) {
+            } else {
+              this.$notify({
+                title: res.code,
+                message: res.msg,
+                type: 'warning',
+                duration: 500
+              })
+            }
+          })
+          .catch(error => {
+            console.error(error.message)
+          })
+      })
+
+      var i = 0
+      player.on('progress', function() {
+        console.log('i = ' + i)
+        if (i % 5 === 0) {
+          playRecord1.currentTime = player.video.currentTime
+          submitPlayRecord(playRecord1)
+            .then(res => {
+              // eslint-disable-next-line no-empty
+              if (res.code === 0) {
+                console.log('播放进度已发送: ' + i)
+              } else {
+                this.$notify({
+                  title: res.code,
+                  message: res.msg,
+                  type: 'warning',
+                  duration: 500
+                })
+              }
+            })
+            .catch(error => {
+              console.error(error.message)
+            })
+        }
+        i++
       })
     },
     initDashPlayer(videoId, coverUrl, videoUrl) {

+ 5 - 4
src/layout/components/head.vue

@@ -47,10 +47,11 @@ export default {
       userInfo: {},
       headItem: [
         { icon: 'mdi-account', text: '个人中心', link: '/studio', id: 0 },
-        { icon: 'mdi-cash-usd', text: '付费会员', link: '/vip', id: 3 },
-        { icon: 'mdi-application', text: '创作中心', link: '/studio', id: 1 },
-        { icon: 'mdi-wrench', text: '自定义频道', link: '/user/setting', id: 4 },
-        { icon: 'mdi-logout', text: '退出', link: '/logout', id: 2 }
+        { icon: 'mdi-application', text: '稍后再看', link: '/studio', id: 2 },
+        { icon: 'mdi-application', text: '收藏列表', link: '/studio', id: 3 },
+        { icon: 'mdi-application', text: '历史记录', link: '/studio', id: 4 },
+        { icon: 'mdi-cash-usd', text: '付费会员', link: '/vip', id: 5 },
+        { icon: 'mdi-logout', text: '退出', link: '/logout', id: 6 }
       ]
     }
   },

+ 3 - 3
src/layout/index.vue

@@ -113,9 +113,9 @@ export default {
     keyword: '',
     items: [
       { icon: 'mdi-home', text: '首页', link: '/' },
-      { icon: 'mdi-trending-up', text: '状态', link: '/hot' },
-      { icon: 'mdi-youtube-subscription', text: '直播', link: '/subscribe' },
-      { icon: 'mdi-history', text: '历史记录', link: '/history' },
+      { icon: 'mdi-history', text: '分区', link: '/channel' },
+      { icon: 'mdi-youtube-subscription', text: '直播', link: '/live' },
+      { icon: 'mdi-trending-up', text: '状态', link: '/status' },
       { icon: 'mdi-playlist-play', text: '稍后再看', link: '/playlist' }
 
     ],

+ 3 - 4
src/layout/studio.vue

@@ -59,7 +59,7 @@
     <v-app-bar
       :clipped-left="$vuetify.breakpoint.lgAndUp"
       app
-      color="red"
+      color="blue"
       dark
     >
       <v-app-bar-nav-icon @click.stop="drawer = !drawer" />
@@ -69,14 +69,14 @@
       >
         <span style="cursor:pointer" @click="goToHome()">{{ this.$store.state.webInfo.name }}</span>
       </v-toolbar-title>
-      <v-text-field
+<!--      <v-text-field
         flat
         solo-inverted
         hide-details
         prepend-inner-icon="mdi-magnify"
         label="搜索"
         class="hidden-sm-and-down"
-      />
+      />-->
       <v-spacer />
       <v-tooltip bottom>
         <template v-slot:activator="{ on, attrs }">
@@ -151,7 +151,6 @@ export default {
     ]
   }),
   mounted() {
-
   },
   created() {
     this.$vuetify.theme.dark = this.$store.state.darkThemOpen

+ 12 - 13
src/router/index.js

@@ -19,22 +19,22 @@ const routes = [
         meta: { title: 'HerTube' }
       },
       {
-        path: '/hot',
-        name: 'Hot',
-        component: () => import('@/views/home/status.vue'),
-        meta: { title: 'HerTube 状态' }
+        path: '/live',
+        name: 'Live',
+        component: () => import('@/views/home/live.vue'),
+        meta: { title: 'HerTube 直播' }
       },
       {
-        path: '/subscribe',
-        name: 'Subscribe',
-        component: () => import('@/views/home/subscribe.vue'),
-        meta: { title: 'HerTube 订阅' }
+        path: '/channel',
+        name: 'Channel',
+        component: () => import('@/views/home/channel.vue'),
+        meta: { title: 'HerTube 分区' }
       },
       {
-        path: '/history',
-        name: 'History',
-        component: () => import('@/views/home/history.vue'),
-        meta: { title: 'HerTube 播放历史' }
+        path: '/status',
+        name: 'Status',
+        component: () => import('@/views/home/status.vue'),
+        meta: { title: 'HerTube 状态' }
       },
       {
         path: '/playlist',
@@ -198,7 +198,6 @@ const routes = [
       title: '404'
     }
   }
-
 ]
 
 const router = new VueRouter({

+ 6 - 4
src/views/404.vue

@@ -1,15 +1,17 @@
 <template>
-  <div>
-    你要找的网页走丢了
+  <div style="text-align: center;">
+    <h1>Not Found!</h1>
+    <p>
+      <a href="/">Go home?</a>
+    </p>
   </div>
 </template>
 
 <script>
 export default {
-
+  name: 'NotFound'
 }
 </script>
 
 <style>
-
 </style>

+ 15 - 0
src/views/home/channel.vue

@@ -0,0 +1,15 @@
+<template>
+  <v-card-text class="text-h5 font-weight-light">
+    分区页面待开发
+  </v-card-text>
+</template>
+
+<script>
+export default {
+  name: 'Channel'
+}
+</script>
+
+<style>
+
+</style>

+ 15 - 0
src/views/home/live.vue

@@ -0,0 +1,15 @@
+<template>
+  <v-card-text class="text-h5 font-weight-light">
+    直播页面待开发
+  </v-card-text>
+</template>
+
+<script>
+export default {
+  name: 'Live'
+}
+</script>
+
+<style>
+
+</style>