Просмотр исходного кода

添加 /s/:shareId 路由和 ShareVideo.vue 页面, 用于展示分享的视频

reghao 9 месяцев назад
Родитель
Сommit
d4c071fdcd
2 измененных файлов с 309 добавлено и 0 удалено
  1. 7 0
      src/router/index.js
  2. 302 0
      src/views/home/ShareVideo.vue

+ 7 - 0
src/router/index.js

@@ -13,6 +13,7 @@ const Login = () => import('views/Login')
 const Register = () => import('views/Register')
 const Forgot = () => import('views/Forgot')
 const Index = () => import('views/Index')
+const ShareVideo = () => import('views/home/ShareVideo')
 
 const Home = () => import('views/home/Home')
 const TimelineIndex = () => import('views/home/Timeline')
@@ -58,6 +59,12 @@ const routes = [
     component: Forgot,
     meta: { needAuth: false }
   },
+  {
+    path: '/s/:shareId',
+    name: 'ShareVideo',
+    component: ShareVideo,
+    meta: { needAuth: false }
+  },
   {
     path: '*',
     name: '404',

+ 302 - 0
src/views/home/ShareVideo.vue

@@ -0,0 +1,302 @@
+<template>
+  <el-main>
+    <router-view />
+    <el-row v-if="video !== null" class="movie-list">
+      <el-col :md="15">
+        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+          <el-card class="box-card">
+            <div slot="header" class="clearfix">
+              <el-row>
+                <el-button style="float: right; padding: 3px 0" type="text" @click="goToVideo">
+                  原视频
+                </el-button>
+              </el-row>
+              <el-row>
+                <h3 v-html="video.title" />
+              </el-row>
+              <el-row style="color: #999;font-size: 16px;padding-top: 0px;">
+                <span><i class="el-icon-video-play">{{ video.view }}</i></span>
+                <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;'" />
+                <span><i class="el-icon-s-comment">{{ video.comment }}</i></span>
+                <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;'" />
+                <span><i class="el-icon-watch">{{ video.pubDate }}</i></span>
+              </el-row>
+            </div>
+            <div class="text item">
+              <div id="dplayer" ref="dplayer" style="height: 480px;" />
+            </div>
+          </el-card>
+        </el-row>
+        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+          <el-card class="box-card">
+            <div class="text item">
+              <!--视频描述行-->
+              <span>
+                <p style="white-space:pre-wrap" v-html="video.description" />
+              </span>
+              <el-divider />
+              <!--视频标签行-->
+              <div>
+                <el-tag
+                  v-for="(tag,index) in video.tags"
+                  :key="index"
+                  class="tag"
+                  size="medium"
+                  effect="plain"
+                >
+                  <router-link style="text-decoration-line: none" target="_blank" :to="`/video/tag/` + tag">
+                    {{ tag }}
+                  </router-link>
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-row>
+      </el-col>
+    </el-row>
+  </el-main>
+</template>
+
+<script>
+import UserAvatarCard from '@/components/card/UserAvatarCard'
+
+import DPlayer from 'dplayer'
+import { videoInfo, videoUrl } from '@/api/video'
+import { getShortVideo } from '@/api/video'
+import { getUserInfo } from '@/api/user'
+import { getAccessToken } from '@/utils/auth'
+
+export default {
+  name: 'ShortVideo',
+  data() {
+    return {
+      // 屏幕宽度, 为了控制分页条的大小
+      screenWidth: document.body.clientWidth,
+      shareId: null,
+      video: null,
+      user: null,
+      userToken: null,
+      danmaku: {
+        api: process.env.VUE_APP_SERVER_URL + '/api/comment/danmaku/'
+      }
+    }
+  },
+  watch: {
+    // 地址栏 url 发生变化时重新加载本页面
+    $route() {
+      this.$router.go()
+    }
+  },
+  created() {
+    this.userToken = getAccessToken()
+    this.shareId = this.$route.params.shareId
+    this.getVideoInfo(this.shareId)
+  },
+  mounted() {
+    const header = this.$refs.header
+    if (header !== undefined && header !== null) {
+      this.wrapStyle = `height: calc(100vh - ${header.clientHeight + 20}px)`
+    }
+  },
+  methods: {
+    // 获取视频的详细信息
+    getVideoInfo(videoId) {
+      videoInfo(videoId).then(resp => {
+        if (resp.code === 0) {
+          this.video = resp.data
+          this.getVideoUrl(this.video.videoId)
+          document.title = resp.data.title
+          this.userId = resp.data.userId
+          getUserInfo(this.userId).then(resp => {
+            if (resp.code === 0) {
+              this.user = resp.data
+            } else {
+              this.$notify.error({
+                message: '用户数据获取失败',
+                type: 'warning',
+                duration: 3000
+              })
+            }
+          })
+        }
+      }).catch(error => {
+        this.$notify.error({
+          message: error.message,
+          type: 'warning',
+          duration: 3000
+        })
+      })
+    },
+    getShortVideoWrapper() {
+      getShortVideo().then(resp => {
+        if (resp.code === 0) {
+          this.video = resp.data
+          document.title = resp.data.title
+          this.getVideoUrl(this.video.videoId)
+          this.userId = resp.data.userId
+          getUserInfo(this.userId).then(resp => {
+            if (resp.code === 0) {
+              this.user = resp.data
+            } else {
+              this.$notify.error({
+                message: '用户数据获取失败',
+                type: 'warning',
+                duration: 3000
+              })
+            }
+          })
+        }
+      }).catch(error => {
+        this.$notify.error({
+          message: error.message,
+          type: 'warning',
+          duration: 3000
+        })
+      })
+    },
+    async getVideoUrl(videoId) {
+      videoUrl(videoId).then(res => {
+        if (res.code === 0) {
+          var sendEvent = false
+          const urlType = res.data.type
+          if (urlType === 'mp4') {
+            const urls = res.data.urls
+            for (const url of urls) {
+              url.type = 'normal'
+            }
+            this.initMp4Player(this.userId, videoId, this.video.coverUrl, urls, res.data.currentTime, sendEvent)
+          } else {
+            this.$notify.error({
+              message: '视频 url 类型不合法',
+              type: 'warning',
+              duration: 3000
+            })
+          }
+        } else {
+          this.$notify.error({
+            message: '视频 url 获取失败',
+            type: 'warning',
+            duration: 3000
+          })
+        }
+      }).catch(error => {
+        this.$notify.error({
+          message: error.message,
+          type: 'error',
+          duration: 3000
+        })
+      })
+    },
+    initMp4Player(userId, videoId, coverUrl, urls, pos, sendEvent) {
+      const player = new DPlayer({
+        container: document.querySelector('#dplayer'),
+        lang: 'zh-cn',
+        screenshot: true,
+        autoplay: false,
+        volume: 0.1,
+        mutex: true,
+        video: {
+          pic: coverUrl,
+          defaultQuality: 0,
+          quality: urls,
+          hotkey: true
+        },
+        danmaku: {
+          id: videoId,
+          maximum: 10000,
+          api: this.danmaku.api,
+          token: this.userToken,
+          bottom: '15%',
+          unlimited: true
+        }
+      })
+
+      // 设置音量
+      // player.volume(0.1, true, false)
+      // 跳转到上次看到的位置
+      player.seek(pos)
+
+      var ended = false
+      /* 事件绑定 */
+      const that = this
+      player.on('play', function() {
+        if (sendEvent) {
+          clearInterval(that.intervalEvent)
+          that.intervalEvent = setInterval(() => {
+            if (!ended) {
+              const payload = {}
+              payload.mediaId = videoId
+              payload.mediaType = 1
+              payload.currentTime = player.video.currentTime
+              payload.ended = ended
+
+              const jsonData = {}
+              jsonData.event = 'media_progress'
+              jsonData.data = JSON.stringify(payload)
+
+              that.wsClient.send(jsonData)
+            }
+          }, 5000)
+        }
+      })
+      player.on('ended', () => {
+        clearInterval(that.intervalEvent)
+        ended = true
+        if (sendEvent) {
+          const payload = {}
+          payload.mediaId = videoId
+          payload.mediaType = 1
+          payload.currentTime = player.video.currentTime
+          payload.ended = ended
+
+          const jsonData = {}
+          jsonData.event = 'media_progress'
+          jsonData.data = JSON.stringify(payload)
+
+          that.wsClient.send(jsonData)
+        }
+      })
+
+      player.on('volumechange', () => {
+        console.log('声音改变')
+      })
+    },
+    goToVideo() {
+      console.log(this.shareId)
+      this.$router.push('/video/' + this.video.videoId)
+    }
+  }
+}
+</script>
+
+<style scoped>
+/*处于手机屏幕时*/
+@media screen and (max-width: 768px) {
+  .movie-list {
+    padding-top: 8px;
+    padding-left: 0.5%;
+    padding-right: 0.5%;
+  }
+}
+
+.movie-list {
+  padding-top: 15px;
+  padding-left: 5%;
+  padding-right: 5%;
+}
+
+.clearfix:before,
+.clearfix:after {
+  display: table;
+  content: "";
+}
+
+.clearfix:after {
+  clear: both;
+}
+
+.logo {
+  width: 30px;
+  position: relative;
+}
+</style>