|
@@ -0,0 +1,682 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <el-row v-if="!permissionDenied" 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>
|
|
|
|
|
+ <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="' '" />
|
|
|
|
|
+ <span><i class="el-icon-s-comment">{{ video.comment }}</i></span>
|
|
|
|
|
+ <span v-html="' '" />
|
|
|
|
|
+ <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 slot="header" class="clearfix">
|
|
|
|
|
+ <div class="video-data-row">
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ icon="el-icon-collection"
|
|
|
|
|
+ :disabled="isCollected"
|
|
|
|
|
+ @click="collection(video.videoId)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>收藏 {{ video.favorite }}</span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ icon="el-icon-thumb"
|
|
|
|
|
+ :disabled="isCollected"
|
|
|
|
|
+ @click="collection(video.videoId)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>喜欢 {{ video.thumbUp }}</span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ icon="el-icon-share"
|
|
|
|
|
+ :disabled="isCollected"
|
|
|
|
|
+ @click="collection(video.videoId)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>分享 {{ video.share }}</span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ icon="el-icon-download"
|
|
|
|
|
+ @click="getDownloadUrl(video.videoId)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>下载</span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="video.cache != null"
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ icon="el-icon-download"
|
|
|
|
|
+ @click="cacheBiliVideo(video.videoId)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>{{ video.cache.msg }}</span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ icon="el-icon-help"
|
|
|
|
|
+ @click="displayErrorReportDialog"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>报错</span>
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text item">
|
|
|
|
|
+ <!--视频描述行-->
|
|
|
|
|
+ <span class="description" v-html="video.description" />
|
|
|
|
|
+ <el-divider />
|
|
|
|
|
+ <!--视频标签行-->
|
|
|
|
|
+ <div class="v-tag">
|
|
|
|
|
+ <el-tag
|
|
|
|
|
+ v-for="(tag,index) in video.tags"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="tag"
|
|
|
|
|
+ size="medium"
|
|
|
|
|
+ effect="plain"
|
|
|
|
|
+ >
|
|
|
|
|
+ <router-link target="_blank" :to="`/video/tag/` + tag">
|
|
|
|
|
+ {{ tag }}
|
|
|
|
|
+ </router-link>
|
|
|
|
|
+ </el-tag>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
|
|
+ <el-card class="box-card">
|
|
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <h3>视频评论</h3>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text item">
|
|
|
|
|
+ <div ref="comment" :style="wrapStyle" class="comment-wrap">
|
|
|
|
|
+ <comment
|
|
|
|
|
+ v-model="videoComments"
|
|
|
|
|
+ :user="currentUser"
|
|
|
|
|
+ :props="props"
|
|
|
|
|
+ :before-submit="submit"
|
|
|
|
|
+ :before-like="like"
|
|
|
|
|
+ :before-delete="deleteComment"
|
|
|
|
|
+ :upload-img="uploadImg"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :md="9">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
|
|
+ <user-avatar-card v-if="user !== null" :user-avatar="user" />
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row v-if="showPlaylist" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
|
|
+ <el-card class="box-card">
|
|
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <h3>播放列表</h3>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <span>自动播放 <el-switch v-model="autoPlay" /></span>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text item">
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ :data="similarVideos"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ prop="title"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
|
+ <router-link target="_blank" :to="`/video/${scope.row.videoId}`">
|
|
|
|
|
+ <span>{{ scope.row.videoId }}</span>
|
|
|
|
|
+ </router-link>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ prop="coverUrl"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template slot-scope="scope">
|
|
|
|
|
+ <span>10:00</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
|
|
+ <el-card class="box-card">
|
|
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <h3>推荐视频</h3>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <span>自动播放 <el-switch v-model="autoPlay" /></span>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text item">
|
|
|
|
|
+ <el-row v-for="(item,index) in similarVideos" :key="index" class="item">
|
|
|
|
|
+ <video-card :video="item" />
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 视频访问码对话框 -->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ append-to-body
|
|
|
|
|
+ :visible.sync="showAccessCodeDialog"
|
|
|
|
|
+ width="30%"
|
|
|
|
|
+ center
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-card class="box-card">
|
|
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
|
|
+ <span>输入视频访问码</span>
|
|
|
|
|
+ <el-button style="float: right; padding: 3px 0" type="text" @click="submitAccessCodeWrapper">提交</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text item">
|
|
|
|
|
+ <el-form ref="form" :model="accessCodeForm" label-width="80px">
|
|
|
|
|
+ <el-form-item label="访问码">
|
|
|
|
|
+ <el-input v-model="accessCodeForm.accessCode" style="width: 70%; padding-right: 2px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 视频报错对话框 -->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ append-to-body
|
|
|
|
|
+ :visible.sync="showErrorReportDialog"
|
|
|
|
|
+ width="30%"
|
|
|
|
|
+ center
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-card class="box-card">
|
|
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
|
|
+ <span>视频报错</span>
|
|
|
|
|
+ <el-button style="float: right; padding: 3px 0" type="text" @click="submitErrorReport">提交错误</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text item">
|
|
|
|
|
+ <el-form ref="form" :model="errorReportForm" label-width="80px">
|
|
|
|
|
+ <el-form-item label="错误类型">
|
|
|
|
|
+ <el-select v-model="errorReportForm.errorCode" placeholder="选择视频错误类型">
|
|
|
|
|
+ <el-option label="视频无封面" value="1" />
|
|
|
|
|
+ <el-option label="视频无声音" value="2" />
|
|
|
|
|
+ <el-option label="视频无画面" value="3" />
|
|
|
|
|
+ <el-option label="视频无资源" value="4" />
|
|
|
|
|
+ <el-option label="视频待删除" value="5" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row v-else>
|
|
|
|
|
+ <permission-denied-card :text-object="textObject" />
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import PermissionDeniedCard from '@/components/card/PermissionDeniedCard'
|
|
|
|
|
+import VideoCard from 'components/card/VideoCard'
|
|
|
|
|
+import UserAvatarCard from '@/components/card/UserAvatarCard'
|
|
|
|
|
+import comment from '@/components/comment'
|
|
|
|
|
+import SocketInstance from '@/utils/ws/socket-instance'
|
|
|
|
|
+
|
|
|
|
|
+import flvjs from 'flv.js'
|
|
|
|
|
+import DPlayer from 'dplayer'
|
|
|
|
|
+
|
|
|
|
|
+import { videoUrl, similarVideo, videoInfo, videoErrorReport, downloadVideo, cacheBiliVideo } from '@/api/video'
|
|
|
|
|
+import { collectItem } from '@/api/collect'
|
|
|
|
|
+import { getUserInfo } from '@/api/user'
|
|
|
|
|
+import { submitAccessCode } from '@/api/content'
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: 'VideoList',
|
|
|
|
|
+ components: { VideoCard, UserAvatarCard, PermissionDeniedCard, comment },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ /** ********************************************************************/
|
|
|
|
|
+ wrapStyle: '',
|
|
|
|
|
+ videoComments: [],
|
|
|
|
|
+ currentUser: {
|
|
|
|
|
+ name: '草莓',
|
|
|
|
|
+ avatar: '//picx.zhimg.com/v2-a2c89378a6332cbfed3e28b5ab84feb7.jpg'
|
|
|
|
|
+ },
|
|
|
|
|
+ props: {
|
|
|
|
|
+ id: 114511,
|
|
|
|
|
+ content: 'this is comment content',
|
|
|
|
|
+ imgSrc: '//oss.reghao.cn/image/a/41e5094eac724efeb2675eea22dd4468.jpg',
|
|
|
|
|
+ children: [],
|
|
|
|
|
+ likes: 0,
|
|
|
|
|
+ liked: false,
|
|
|
|
|
+ reply: null,
|
|
|
|
|
+ createAt: 'createAt',
|
|
|
|
|
+ user: {
|
|
|
|
|
+ name: '芒果',
|
|
|
|
|
+ avatar: '//oss.reghao.cn/image/a/41e5094eac724efeb2675eea22dd4468.jpg'
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ // **********************************************************************/
|
|
|
|
|
+ video: null,
|
|
|
|
|
+ user: null,
|
|
|
|
|
+ similarVideos: [],
|
|
|
|
|
+ isCollected: false,
|
|
|
|
|
+ showAccessCodeDialog: false,
|
|
|
|
|
+ accessCodeForm: {
|
|
|
|
|
+ contentId: null,
|
|
|
|
|
+ contentType: 1002,
|
|
|
|
|
+ accessCode: null
|
|
|
|
|
+ },
|
|
|
|
|
+ showErrorReportDialog: false,
|
|
|
|
|
+ errorReportForm: {
|
|
|
|
|
+ videoId: null,
|
|
|
|
|
+ errorCode: null
|
|
|
|
|
+ },
|
|
|
|
|
+ permissionDenied: false,
|
|
|
|
|
+ textObject: {
|
|
|
|
|
+ content: '视频',
|
|
|
|
|
+ route: '/video'
|
|
|
|
|
+ },
|
|
|
|
|
+ showPlaylist: false,
|
|
|
|
|
+ autoPlay: false,
|
|
|
|
|
+ playList: {
|
|
|
|
|
+ current: 0,
|
|
|
|
|
+ list: [
|
|
|
|
|
+ 'eyNXaDnmN3',
|
|
|
|
|
+ 'WkYNYzDePp',
|
|
|
|
|
+ 'a8Vx9EGDbA',
|
|
|
|
|
+ 'a8V3D88NJK',
|
|
|
|
|
+ '4m7qMXapp1'
|
|
|
|
|
+ ]
|
|
|
|
|
+ },
|
|
|
|
|
+ // **********************************************************************/
|
|
|
|
|
+ flvjs,
|
|
|
|
|
+ DPlayer,
|
|
|
|
|
+ danmaku: {
|
|
|
|
|
+ api: '//api.reghao.cn/api/comment/danmaku/',
|
|
|
|
|
+ token: 'bili'
|
|
|
|
|
+ },
|
|
|
|
|
+ getUrl: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ watch: {
|
|
|
|
|
+ // 地址栏 url 发生变化时重新加载本页面
|
|
|
|
|
+ $route() {
|
|
|
|
|
+ this.$router.go()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ created() {
|
|
|
|
|
+ const videoId = this.$route.params.id
|
|
|
|
|
+ this.accessCodeForm.contentId = videoId
|
|
|
|
|
+ this.getVideoInfo(videoId)
|
|
|
|
|
+ this.getSimilarVideos(videoId)
|
|
|
|
|
+ },
|
|
|
|
|
+ mounted() {
|
|
|
|
|
+ const header = this.$refs.header
|
|
|
|
|
+ if (header !== null) {
|
|
|
|
|
+ this.wrapStyle = `height: calc(100vh - ${header.clientHeight + 20}px)`
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ // 获取视频的详细信息
|
|
|
|
|
+ getVideoInfo(videoId) {
|
|
|
|
|
+ videoInfo(videoId).then(resp => {
|
|
|
|
|
+ if (resp.code === 0) {
|
|
|
|
|
+ // this.showAccessCodeDialog = true
|
|
|
|
|
+ this.video = resp.data
|
|
|
|
|
+ document.title = resp.data.title
|
|
|
|
|
+ this.getVideoUrl(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
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ } else if (resp.code === 2) {
|
|
|
|
|
+ this.$router.push('/404')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.permissionDenied = true
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$notify.error({
|
|
|
|
|
+ message: error.message,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ // 获取和当前视频类似的其他视频
|
|
|
|
|
+ getSimilarVideos(videoId) {
|
|
|
|
|
+ similarVideo(videoId).then(resp => {
|
|
|
|
|
+ if (resp.code === 0) {
|
|
|
|
|
+ // this.similarVideos = resp.data
|
|
|
|
|
+ this.playList.list = resp.data
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$notify.error({
|
|
|
|
|
+ message: '推荐视频数据获取失败',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$notify.error({
|
|
|
|
|
+ message: error.message,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ // 换一换
|
|
|
|
|
+ refreshSimilar() {
|
|
|
|
|
+ console.log('刷新相关推荐')
|
|
|
|
|
+ },
|
|
|
|
|
+ // 用户点击收藏
|
|
|
|
|
+ collection(videoId) {
|
|
|
|
|
+ const jsonData = {}
|
|
|
|
|
+ jsonData.contentType = 1002
|
|
|
|
|
+ jsonData.contentId = videoId
|
|
|
|
|
+ jsonData.collected = true
|
|
|
|
|
+ collectItem(jsonData).then(resp => {
|
|
|
|
|
+ if (resp.code !== 0) {
|
|
|
|
|
+ this.$notify.success({
|
|
|
|
|
+ title: '视频收藏失败',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ getDownloadUrl(videoId) {
|
|
|
|
|
+ // let filename
|
|
|
|
|
+ downloadVideo(videoId).then(resp => {
|
|
|
|
|
+ if (resp.code === 0) {
|
|
|
|
|
+ const downloadUrl = resp.data.url
|
|
|
|
|
+ window.open(downloadUrl, '_blank')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ message: resp.msg,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ message: error.message,
|
|
|
|
|
+ type: 'error',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ cacheBiliVideo(bvId) {
|
|
|
|
|
+ cacheBiliVideo(bvId).then(resp => {
|
|
|
|
|
+ if (resp.code === 0) {
|
|
|
|
|
+ const resData = resp.data
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ message: resData.msg,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ submitAccessCodeWrapper() {
|
|
|
|
|
+ submitAccessCode(this.accessCodeForm).then(resp => {
|
|
|
|
|
+ if (resp.code === 0) {
|
|
|
|
|
+ this.video = resp.data
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ message: resp.msg,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ message: error.message,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ displayErrorReportDialog() {
|
|
|
|
|
+ this.errorReportForm.videoId = this.video.videoId
|
|
|
|
|
+ this.showErrorReportDialog = true
|
|
|
|
|
+ },
|
|
|
|
|
+ submitErrorReport() {
|
|
|
|
|
+ this.showErrorReportDialog = false
|
|
|
|
|
+ videoErrorReport(this.errorReportForm).then(resp => {
|
|
|
|
|
+ if (resp.code === 0) {
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ message: '视频错误已提交',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$notify({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ message: error.message,
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ // ****************************************************************************************************************
|
|
|
|
|
+ getVideoUrl(videoId) {
|
|
|
|
|
+ videoUrl(videoId).then(res => {
|
|
|
|
|
+ if (res.code === 0) {
|
|
|
|
|
+ SocketInstance.connect()
|
|
|
|
|
+
|
|
|
|
|
+ const urlType = res.data.type
|
|
|
|
|
+ if (urlType === 'mp4') {
|
|
|
|
|
+ const urls = res.data.urls
|
|
|
|
|
+ for (const url of urls) {
|
|
|
|
|
+ url.type = 'normal'
|
|
|
|
|
+ }
|
|
|
|
|
+ const autoPlay = false
|
|
|
|
|
+ this.initMp4Player(this.video.userId, videoId, this.video.coverUrl, urls, res.data.currentTime, autoPlay)
|
|
|
|
|
+ } 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, autoPlay) {
|
|
|
|
|
+ const player = new DPlayer({
|
|
|
|
|
+ container: document.querySelector('#dplayer'),
|
|
|
|
|
+ lang: 'zh-cn',
|
|
|
|
|
+ logo: '/logo.png',
|
|
|
|
|
+ screenshot: false,
|
|
|
|
|
+ autoplay: autoPlay,
|
|
|
|
|
+ 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.danmaku.token,
|
|
|
|
|
+ user: userId,
|
|
|
|
|
+ bottom: '15%',
|
|
|
|
|
+ unlimited: true
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 设置音量
|
|
|
|
|
+ // player.volume(0.1, true, false)
|
|
|
|
|
+ // 跳转到上次看到的位置
|
|
|
|
|
+ player.seek(pos)
|
|
|
|
|
+
|
|
|
|
|
+ /* 事件绑定 */
|
|
|
|
|
+ player.on('progress', function() {
|
|
|
|
|
+ const jsonData = {}
|
|
|
|
|
+ jsonData.videoId = videoId
|
|
|
|
|
+ jsonData.currentTime = player.video.currentTime
|
|
|
|
|
+ SocketInstance.send(jsonData)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ player.on('ended', () => {
|
|
|
|
|
+ const jsonData = {}
|
|
|
|
|
+ jsonData.videoId = videoId
|
|
|
|
|
+ jsonData.currentTime = player.video.currentTime
|
|
|
|
|
+ SocketInstance.send(jsonData)
|
|
|
|
|
+
|
|
|
|
|
+ const nextPath = this.getNextPath()
|
|
|
|
|
+ if (nextPath !== null) {
|
|
|
|
|
+ console.log('播放下一个视频')
|
|
|
|
|
+ this.$router.push(nextPath)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log('视频播放完成')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ player.on('volumechange', () => {
|
|
|
|
|
+ console.log('声音改变')
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ getNextPath() {
|
|
|
|
|
+ let current = this.playList.current
|
|
|
|
|
+ if (current !== this.playList.list.length) {
|
|
|
|
|
+ current += 1
|
|
|
|
|
+ return this.playList.list[current]
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return null
|
|
|
|
|
+ },
|
|
|
|
|
+ // ****************************************************************************************************************
|
|
|
|
|
+ async submit(newComment, parent, add) {
|
|
|
|
|
+ const res = await new Promise((resolve) => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ resolve({ newComment, parent })
|
|
|
|
|
+ }, 300)
|
|
|
|
|
+ })
|
|
|
|
|
+ add(Object.assign(res.newComment, { _id: new Date().getTime() }))
|
|
|
|
|
+ console.log('addComment: ', res)
|
|
|
|
|
+ },
|
|
|
|
|
+ async like(comment) {
|
|
|
|
|
+ const res = await new Promise((resolve) => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ resolve(comment)
|
|
|
|
|
+ }, 0)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ console.log('likeComment: ', res)
|
|
|
|
|
+ },
|
|
|
|
|
+ async uploadImg({ file, callback }) {
|
|
|
|
|
+ const res = await new Promise((resolve, reject) => {
|
|
|
|
|
+ const reader = new FileReader()
|
|
|
|
|
+
|
|
|
|
|
+ reader.readAsDataURL(file)
|
|
|
|
|
+
|
|
|
|
|
+ reader.onload = () => {
|
|
|
|
|
+ resolve(reader.result)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ reader.onerror = () => {
|
|
|
|
|
+ reject(reader.error)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ callback(res)
|
|
|
|
|
+ console.log('uploadImg: ', res)
|
|
|
|
|
+ },
|
|
|
|
|
+ async deleteComment(comment, parent) {
|
|
|
|
|
+ const res = await new Promise((resolve) => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ resolve({ comment, parent })
|
|
|
|
|
+ }, 300)
|
|
|
|
|
+ })
|
|
|
|
|
+ console.log('deleteComment: ', res)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</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;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.v-tag {
|
|
|
|
|
+ padding-top: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+.tag{
|
|
|
|
|
+ margin-right: 3px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|