| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <!-- eslint-disable -->
- <template>
- <view
- v-html="videoHtml"
- id="dom-video"
- class="dom-video"
- :eventDrive="eventDrive"
- :change:eventDrive="domVideo.eventHandle"
- :videoSrc="videoSrc"
- :change:videoSrc="domVideo.srcChange"
- :videoProps="videoProps"
- :change:videoProps="domVideo.propsChange"
- :randomNum="randomNum"
- :change:randomNum="domVideo.randomNumChange"
- />
- </template>
- <script>
- export default {
- props: {
- src: {
- type: String,
- default: '',
- },
- autoplay: {
- type: Boolean,
- default: false,
- },
- loop: {
- type: Boolean,
- default: false,
- },
- controls: {
- type: Boolean,
- default: false,
- },
- objectFit: {
- type: String,
- default: 'contain',
- },
- muted: {
- type: Boolean,
- default: false,
- },
- poster: {
- type: String,
- default: '',
- },
- },
- // 数据状态
- data() {
- return {
- videoHtml: '',
- videoSrc: '',
- eventDrive: null,
- videoProps: {},
- randomNum: Math.floor(Math.random() * 100000000 + 1),
- };
- },
- watch: {
- // 监听视频资源文件更新
- src: {
- handler(val) {
- if (!val) return;
- this.initVideoHtml();
- setTimeout(() => {
- this.videoSrc = val;
- }, 0);
- },
- immediate: true,
- },
- // 监听首次加载
- autoplay: {
- handler(val) {
- this.videoProps.autoplay = val;
- },
- immediate: true,
- },
- },
- // 生命周期
- mounted() {
- this.initVideoHtml();
- },
- // 方法
- methods: {
- // 将video的事件传递给父组件
- videoEvent(data) {
- // console.log('向父组件传递事件 =>', data)
- this.$emit(data);
- },
- // 初始化视频
- initVideoHtml() {
- this.videoHtml = `<video
- src="${this.src}"
- id="dom-html-video_${this.randomNum}"
- class="dom-html-video"
- ${this.autoplay ? 'autoplay' : ''}
- ${this.loop ? 'loop' : ''}
- ${this.controls ? 'controls' : ''}
- ${this.muted ? 'muted' : ''}
- ${this.poster ? 'poster="' + this.poster + '"' : ''}
- preload="auto"
- playsinline
- webkit-playsinline
- width="100%"
- height="100%"
- style="object-fit: ${this.objectFit};padding:0;"
- >
- <source src="${this.src}" type="video/mp4">
- <source src="${this.src}" type="video/ogg">
- <source src="${this.src}" type="video/webm">
- </video>
- `;
- // console.log('视频html =>', this.videoHtml)
- },
- resetEventDrive() {
- this.eventDrive = null;
- },
- // 将service层的事件/数据 => 传递给renderjs层
- play() {
- this.eventDrive = 'play';
- },
- pause() {
- this.eventDrive = 'pause';
- },
- stop() {
- this.eventDrive = 'stop';
- },
- },
- };
- </script>
- <script module="domVideo" lang="renderjs">
- export default {
- data() {
- return {
- video: null,
- num: '',
- options: {}
- }
- },
- mounted() {
- this.initVideoEvent()
- },
- methods: {
- initVideoEvent() {
- setTimeout(() => {
- let video = document.getElementById(`dom-html-video_${this.num}`)
- this.video = video
- // 监听视频事件
- video.addEventListener('play', () => {
- this.$ownerInstance.callMethod('videoEvent', 'play')
- })
- video.addEventListener('pause', () => {
- this.$ownerInstance.callMethod('videoEvent', 'pause')
- })
- video.addEventListener('ended', () => {
- this.$ownerInstance.callMethod('videoEvent', 'ended')
- this.$ownerInstance.callMethod('resetEventDrive')
- })
- }, 100)
- },
- eventHandle(eventType) {
- if (eventType) {
- this.video = document.getElementById(`dom-html-video_${this.num}`)
- if (eventType === 'play') {
- this.video.play()
- } else if (eventType === 'pause') {
- this.video.pause()
- } else if (eventType === 'stop') {
- this.video.stop()
- }
- }
- },
- srcChange(val) {
- // 实现视频的第一帧作为封面,避免视频展示黑屏
- this.initVideoEvent()
- setTimeout(() => {
- let video = document.getElementById(`dom-html-video_${this.num}`)
- video.addEventListener('loadedmetadata', () => {
- let { autoplay } = this.options
- video.play()
- if (!autoplay) {
- video.pause()
- }
- })
- }, 0)
- },
- propsChange(obj) {
- this.options = obj
- },
- randomNumChange(val) {
- this.num = val
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- .dom-video {
- overflow: hidden;
- height: 100%;
- padding: 0;
- &-height {
- height: 100%;
- }
- }
- </style>
|