|
|
@@ -23,18 +23,18 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import Vue from 'vue' |
|
|
|
import { Toast, Dialog } from 'vant' |
|
|
|
import { mapState, mapActions } from 'vuex' |
|
|
|
import HeadTop from './../../components/common/head.vue' |
|
|
|
import Vue from 'vue'; |
|
|
|
import { Toast, Dialog } from 'vant'; |
|
|
|
import { mapState, mapActions } from 'vuex'; |
|
|
|
import HeadTop from './../../components/common/head.vue'; |
|
|
|
// 工具 |
|
|
|
import { scrollToID, getDeviceType } from '../../utils' |
|
|
|
import { saveAs } from 'file-saver' |
|
|
|
import { scrollToID, getDeviceType } from '../../utils'; |
|
|
|
import { saveAs } from 'file-saver'; |
|
|
|
|
|
|
|
// 接口 |
|
|
|
import { getModelDetailById } from '../../api/getPaper' |
|
|
|
import { doGetVideoDetialById } from '../../api/downloadVideo' |
|
|
|
Vue.use(Toast) |
|
|
|
import { getModelDetailById } from '../../api/getPaper'; |
|
|
|
import { doGetVideoDetialById } from '../../api/downloadVideo'; |
|
|
|
Vue.use(Toast); |
|
|
|
|
|
|
|
export default { |
|
|
|
components: { |
|
|
@@ -47,39 +47,40 @@ export default { |
|
|
|
// 'https://wenlian.wenzhou.gov.cn:8001//upload/video/%E3%80%8A%E7%93%AF%E8%B6%8A%E4%B9%8B%E5%8D%8E%E3%80%8B%E7%89%87%E8%8A%B11.mp4', |
|
|
|
videoSrc: null, //播放地址路径 |
|
|
|
title: null, // 视频名称 |
|
|
|
coverUrl: null //封面图 |
|
|
|
} |
|
|
|
coverUrl: null, //封面图 |
|
|
|
height: null |
|
|
|
}; |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
...mapState({ |
|
|
|
characters: (state) => state.publicObj.characters |
|
|
|
characters: state => state.publicObj.characters |
|
|
|
}) |
|
|
|
}, |
|
|
|
created() {}, |
|
|
|
async mounted() { |
|
|
|
this.inPage = true |
|
|
|
scrollToID('top') |
|
|
|
this.inPage = true; |
|
|
|
scrollToID('top'); |
|
|
|
//初始化数据 |
|
|
|
await this.getVideoInfo() |
|
|
|
this.open() |
|
|
|
await this.getVideoInfo(); |
|
|
|
this.open(); |
|
|
|
}, |
|
|
|
destroyed() {}, |
|
|
|
methods: { |
|
|
|
// 创建阿里云播放器 |
|
|
|
open() { |
|
|
|
// 检测设备类型 |
|
|
|
const deviceType = getDeviceType() |
|
|
|
let isAndroid = false |
|
|
|
const deviceType = getDeviceType(); |
|
|
|
let isAndroid = false; |
|
|
|
if (!deviceType) { |
|
|
|
// 设备类型为pc |
|
|
|
isAndroid = false |
|
|
|
isAndroid = false; |
|
|
|
} else { |
|
|
|
if (deviceType[0] == 'Android') { |
|
|
|
// 设备类型为安卓 |
|
|
|
isAndroid = true |
|
|
|
isAndroid = true; |
|
|
|
} else { |
|
|
|
// 其他设备 |
|
|
|
isAndroid = false |
|
|
|
isAndroid = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -92,7 +93,7 @@ export default { |
|
|
|
// width: isAndroid ? '260px' : '480px', |
|
|
|
// height: isAndroid ? '427px' : '854px', |
|
|
|
width: '100%', |
|
|
|
height: '100%', |
|
|
|
height: this.height < 1920 ? '35%' : '100%', |
|
|
|
// 以下可选设置 |
|
|
|
playsinline: true, // 禁止内置播放 |
|
|
|
isLive: false, // 直播 |
|
|
@@ -106,103 +107,102 @@ export default { |
|
|
|
controlBarVisibility: 'always' // 控制条的显示方式 |
|
|
|
}, |
|
|
|
function (player) { |
|
|
|
player.play() |
|
|
|
player.play(); |
|
|
|
player.setCoverScale(9, 16); |
|
|
|
} |
|
|
|
) |
|
|
|
); |
|
|
|
}, |
|
|
|
// 下载视频 |
|
|
|
async downloadVideo() { |
|
|
|
// 视频地址 |
|
|
|
let that = this |
|
|
|
const videoUrl = this.videoSrc |
|
|
|
const title = this.sanitizeFilename(this.title) |
|
|
|
let that = this; |
|
|
|
const videoUrl = this.videoSrc; |
|
|
|
const title = this.sanitizeFilename(this.title); |
|
|
|
// ios |
|
|
|
const deviceType = getDeviceType() |
|
|
|
let isAndroid = false |
|
|
|
const deviceType = getDeviceType(); |
|
|
|
let isAndroid = false; |
|
|
|
if (!deviceType) { |
|
|
|
// 设备类型为pc |
|
|
|
isAndroid = false |
|
|
|
isAndroid = false; |
|
|
|
} else { |
|
|
|
if (deviceType[0] == 'Android') { |
|
|
|
// 设备类型为安卓 |
|
|
|
isAndroid = true |
|
|
|
isAndroid = true; |
|
|
|
} else { |
|
|
|
// 其他设备 |
|
|
|
isAndroid = false |
|
|
|
isAndroid = false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!isAndroid) { |
|
|
|
console.log('ios') |
|
|
|
console.log('ios'); |
|
|
|
// await this.downloadFun( |
|
|
|
// this.videoSrc + '?response-content-type=application/octet-stream', |
|
|
|
// this.title + '.mp4' |
|
|
|
// ) |
|
|
|
// await this.downloadFile1(this.videoSrc) |
|
|
|
window.open(this.videoSrc, '_self') |
|
|
|
window.open(this.videoSrc, '_self'); |
|
|
|
} else { |
|
|
|
// 下载视频 |
|
|
|
saveAs(videoUrl, this.title + '.mp4') |
|
|
|
saveAs(videoUrl, this.title + '.mp4'); |
|
|
|
} |
|
|
|
}, |
|
|
|
// 视频名转化 |
|
|
|
sanitizeFilename(filename) { |
|
|
|
return filename.replace(/[/\\:?*"<>|]/g, '').trim() |
|
|
|
return filename.replace(/[/\\:?*"<>|]/g, '').trim(); |
|
|
|
}, |
|
|
|
// ios下载处理 |
|
|
|
downloadFile1(url) { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
const xhr = new XMLHttpRequest() |
|
|
|
xhr.open('GET', url, true) |
|
|
|
xhr.responseType = 'arraybuffer' |
|
|
|
const xhr = new XMLHttpRequest(); |
|
|
|
xhr.open('GET', url, true); |
|
|
|
xhr.responseType = 'arraybuffer'; |
|
|
|
xhr.onload = () => { |
|
|
|
if (xhr.status === 200) { |
|
|
|
const contentType = xhr.getResponseHeader('Content-Type') |
|
|
|
const blob = new Blob([xhr.response], { type: contentType }) |
|
|
|
const reader = new FileReader() |
|
|
|
reader.readAsDataURL(blob) |
|
|
|
const contentType = xhr.getResponseHeader('Content-Type'); |
|
|
|
const blob = new Blob([xhr.response], { type: contentType }); |
|
|
|
const reader = new FileReader(); |
|
|
|
reader.readAsDataURL(blob); |
|
|
|
reader.onloadend = function () { |
|
|
|
const base64Data = reader.result |
|
|
|
const link = document.createElement('a') |
|
|
|
link.href = base64Data |
|
|
|
link.download = fileName |
|
|
|
document.body.appendChild(link) |
|
|
|
link.click() |
|
|
|
document.body.removeChild(link) |
|
|
|
} |
|
|
|
resolve(blob) |
|
|
|
const base64Data = reader.result; |
|
|
|
const link = document.createElement('a'); |
|
|
|
link.href = base64Data; |
|
|
|
link.download = fileName; |
|
|
|
document.body.appendChild(link); |
|
|
|
link.click(); |
|
|
|
document.body.removeChild(link); |
|
|
|
}; |
|
|
|
resolve(blob); |
|
|
|
} else { |
|
|
|
reject( |
|
|
|
new Error(`Failed to download file, status code: ${xhr.status}`) |
|
|
|
) |
|
|
|
reject(new Error(`Failed to download file, status code: ${xhr.status}`)); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
xhr.onerror = () => { |
|
|
|
reject(new Error(`Failed to download file, network error`)) |
|
|
|
} |
|
|
|
reject(new Error(`Failed to download file, network error`)); |
|
|
|
}; |
|
|
|
|
|
|
|
xhr.send() |
|
|
|
}) |
|
|
|
xhr.send(); |
|
|
|
}); |
|
|
|
}, |
|
|
|
async downloadFun(blobFile, fileName) { |
|
|
|
let blob = new Blob([blobFile], { |
|
|
|
type: 'application/pdf;charset=UTF-8' |
|
|
|
}) |
|
|
|
console.log(blob) |
|
|
|
}); |
|
|
|
console.log(blob); |
|
|
|
if (window.navigator.msSaveOrOpenBlob) { |
|
|
|
navigator.msSaveBlob(blob, fileName) |
|
|
|
navigator.msSaveBlob(blob, fileName); |
|
|
|
} else { |
|
|
|
const reader = new FileReader() |
|
|
|
reader.readAsDataURL(blob) |
|
|
|
const reader = new FileReader(); |
|
|
|
reader.readAsDataURL(blob); |
|
|
|
reader.onloadend = function () { |
|
|
|
const base64Data = reader.result |
|
|
|
const link = document.createElement('a') |
|
|
|
link.href = base64Data |
|
|
|
link.download = fileName |
|
|
|
document.body.appendChild(link) |
|
|
|
link.click() |
|
|
|
document.body.removeChild(link) |
|
|
|
} |
|
|
|
const base64Data = reader.result; |
|
|
|
const link = document.createElement('a'); |
|
|
|
link.href = base64Data; |
|
|
|
link.download = fileName; |
|
|
|
document.body.appendChild(link); |
|
|
|
link.click(); |
|
|
|
document.body.removeChild(link); |
|
|
|
}; |
|
|
|
// const dataUrl = 'data:application/octet-stream;base64,' + blobFile |
|
|
|
// const a = document.createElement('a') |
|
|
|
// a.style.display = 'none' |
|
|
@@ -222,32 +222,33 @@ export default { |
|
|
|
}, |
|
|
|
// 获取视频信息 |
|
|
|
async getVideoInfo() { |
|
|
|
const { data: res } = await getModelDetailById(this.$route.query.id) |
|
|
|
const { data: res } = await getModelDetailById(this.$route.query.id); |
|
|
|
if (res.videoId) { |
|
|
|
const { data: res2 } = await doGetVideoDetialById(res.videoId) |
|
|
|
this.videoSrc = res2.videoUrl |
|
|
|
this.title = res2.title |
|
|
|
this.coverUrl = res2.coverURL |
|
|
|
return |
|
|
|
const { data: res2 } = await doGetVideoDetialById(res.videoId); |
|
|
|
this.videoSrc = res2.videoUrl; |
|
|
|
this.title = res2.title; |
|
|
|
this.coverUrl = res2.coverURL; |
|
|
|
this.height = res2.height; |
|
|
|
return; |
|
|
|
} |
|
|
|
this.videoSrc = res.videoPathUri + res.videoPath |
|
|
|
this.title = res.title |
|
|
|
this.coverUrl = res.coverURL |
|
|
|
this.videoSrc = res.videoPathUri + res.videoPath; |
|
|
|
this.title = res.title; |
|
|
|
this.coverUrl = res.coverURL; |
|
|
|
}, |
|
|
|
|
|
|
|
// 处理时间 |
|
|
|
formatTime(time) { |
|
|
|
const minutes = Math.floor(time / 60) |
|
|
|
const seconds = Math.round(time % 60) |
|
|
|
return `${minutes}:${seconds.toString().padStart(2, '0')}` |
|
|
|
const minutes = Math.floor(time / 60); |
|
|
|
const seconds = Math.round(time % 60); |
|
|
|
return `${minutes}:${seconds.toString().padStart(2, '0')}`; |
|
|
|
}, |
|
|
|
...mapActions(['setCharacters']), |
|
|
|
|
|
|
|
go(url) { |
|
|
|
this.$router.push(url) |
|
|
|
this.$router.push(url); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
</script> |
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
@@ -268,6 +269,8 @@ export default { |
|
|
|
overflow: hidden; |
|
|
|
} |
|
|
|
.videoBox { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
position: relative; |
|
|
|
width: 100%; |
|
|
|
height: calc(100vh - 40px); |
|
|
|