Vimeo SDK:初始化后出现未知播放器错误(VueJS)
Vimeo SDK : Unknown Player Error after Initialization (VueJS)
我想使用 Vimeo 播放器在 Vue 网站上显示一堆视频。
为此,我创建了一个为每个视频创建的 VideoPlayer-Component:
<template>
<div class="video-element__container">
<div class="video-element__player" ref="player" @click="$emit('shrink')"></div>
<div class="video-element__play-button" @click="play()"></div>
</div>
</template>
<script>
import Player from '@vimeo/player'
export default {
name: 'VideoPlayer',
props: ['isActive', 'id'],
data () {
return {
player: null,
}
},
mounted() {
this.initPlayer()
},
components: {
},
methods:
{
async play () {
try {
await this.player.play()
this.isPlaying = true
} catch (e) {
console.log(e)
}
},
pause() {
this.player.pause()
this.isPlaying = false
},
initPlayer () {
let options = {
url: 'https://vimeo.com/393632283',
loop: false,
controls: false,
muted: true,
};
let iframe = this.$refs.player
this.player = new Player(iframe, options);
}
}
}
</script>
但是,每当我单击 'play' 时,都会出现以下错误:
Uncaught (in promise) Error: Unknown player. Probably unloaded.
at readyPromise (player.es.js?84c9:1458)
at new Promise (<anonymous>)
at Proxy.ready (player.es.js?84c9:1457)
at eval (player.es.js?84c9:1311)
at new Promise (<anonymous>)
at Proxy.get (player.es.js?84c9:1306)
at Proxy.getDuration (player.es.js?84c9:2052)
at Proxy.initPlayer (VideoPlayer.vue?5912:93)
at Proxy.play (VideoPlayer.vue?5912:53)
at Object.onClick._cache.<computed>._cache.<computed> (VideoPlayer.vue?5912:17)
然而,当我使用 Vimeo 控件时,它工作得很好。
有人可以在这里看到问题吗?谢谢!
我想你使用的是 Vue 3,因为你的代码对我来说在 Vue 2 上工作得很好,而我在 Vue 3 上遇到了同样的错误。
对于 Vue 3,您需要使用 setup()
方法稍微重构您的代码,如下所示:
<template>
<div class="video-element__container">
<div class="video-element__player" ref="playerRef" @click="$emit('shrink')"></div>
<div class="video-element__play-button" @click="play()"></div>
</div>
</template>
<script>
import {ref, onMounted} from 'vue';
import Player from '@vimeo/player';
export default {
name: 'VideoPlayer',
setup() {
let player;
let isPlaying = false;
const playerRef = ref(null);
onMounted(() => {
const options = {
url: 'https://vimeo.com/393632283',
loop: false,
controls: false,
muted: true,
};
player = new Player(playerRef.value, options);
});
const play = () => {
player.play()
.then(isPlaying = true)
.catch(e => console.log(e));
};
const pause = () => {
player.pause()
isPlaying = false
};
return {
player, isPlaying, playerRef, play, pause
}
}
}
</script>
上面的代码已经过测试并按预期工作。
您可以查看 Template Refs for more information how to access HTML element inside setup()
. Regarding the setup()
method itself, please check the Composition API 文档。
此外,还有一些 Vimeo SDK 的 Vue 包装器,例如vue-vimeo-player
。如果你愿意,你可以使用它们而不是自己编写。
即使 Triet Doan 的回答现在被接受了,我也不喜欢它。它需要在 Options API 中编写的整个 OP 代码并将其重写为 Composition API 而没有解释为什么需要它...
嗯,根本不需要!事实上,最简单的修复原始代码的方法是在 data()
中注释掉 player: null
(如下面的演示所示)
为什么
Vue 的反应性可能有点打扰。使用 Object.defineProperty() (used for reactivity in Vue 2) and proxies 创建的 getters/setters (用于 Vue 3 中的反应性)都可以改变行为,特别是对于复杂数据 types/classes,就像 Vimeo Player 一样。
要解决此类问题,请不要将此类复杂对象放入 data()
或不要将它们包装在 ref()
或 reactive()
中。在大多数情况下,无论如何,您不需要 Vue 模板对此类复杂对象的某些内部状态作出反应....
而是将它们添加到实例中作为 this.player = new ...
in mounted
hook 或将它们声明为普通变量(没有 ref()
或 reactive()
)在 setup()
const app = Vue.createApp({
name: 'VideoPlayer',
data() {
return {
// player: null, <-- THIS LITTLE CHANGE IS NEEDED
}
},
mounted() {
this.initPlayer()
},
methods: {
async play() {
try {
await this.player.play()
this.isPlaying = true
} catch (e) {
console.log(e)
}
},
pause() {
this.player.pause()
this.isPlaying = false
},
initPlayer() {
let options = {
url: 'https://vimeo.com/393632283',
loop: false,
controls: false,
muted: true,
};
let element = this.$refs.player
this.player = new Vimeo.Player(element, options);
}
}
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.2.2/dist/vue.global.js"></script>
<script src="https://player.vimeo.com/api/player.js"></script>
<div id="app">
<div class="video-element__container">
<div class="video-element__player" ref="player" @click="$emit('shrink')"></div>
<div class="video-element__play-button" @click="play()"></div>
</div>
</div>
警告
另一方面,我完全同意使用existing wrapper - vue-vimeo-player. Because it handles some edge cases and more importantly the unloading of the player when the component is destroyed. Without it, you are creating a memory leak in your app
的建议
我想使用 Vimeo 播放器在 Vue 网站上显示一堆视频。
为此,我创建了一个为每个视频创建的 VideoPlayer-Component:
<template>
<div class="video-element__container">
<div class="video-element__player" ref="player" @click="$emit('shrink')"></div>
<div class="video-element__play-button" @click="play()"></div>
</div>
</template>
<script>
import Player from '@vimeo/player'
export default {
name: 'VideoPlayer',
props: ['isActive', 'id'],
data () {
return {
player: null,
}
},
mounted() {
this.initPlayer()
},
components: {
},
methods:
{
async play () {
try {
await this.player.play()
this.isPlaying = true
} catch (e) {
console.log(e)
}
},
pause() {
this.player.pause()
this.isPlaying = false
},
initPlayer () {
let options = {
url: 'https://vimeo.com/393632283',
loop: false,
controls: false,
muted: true,
};
let iframe = this.$refs.player
this.player = new Player(iframe, options);
}
}
}
</script>
但是,每当我单击 'play' 时,都会出现以下错误:
Uncaught (in promise) Error: Unknown player. Probably unloaded.
at readyPromise (player.es.js?84c9:1458)
at new Promise (<anonymous>)
at Proxy.ready (player.es.js?84c9:1457)
at eval (player.es.js?84c9:1311)
at new Promise (<anonymous>)
at Proxy.get (player.es.js?84c9:1306)
at Proxy.getDuration (player.es.js?84c9:2052)
at Proxy.initPlayer (VideoPlayer.vue?5912:93)
at Proxy.play (VideoPlayer.vue?5912:53)
at Object.onClick._cache.<computed>._cache.<computed> (VideoPlayer.vue?5912:17)
然而,当我使用 Vimeo 控件时,它工作得很好。 有人可以在这里看到问题吗?谢谢!
我想你使用的是 Vue 3,因为你的代码对我来说在 Vue 2 上工作得很好,而我在 Vue 3 上遇到了同样的错误。
对于 Vue 3,您需要使用 setup()
方法稍微重构您的代码,如下所示:
<template>
<div class="video-element__container">
<div class="video-element__player" ref="playerRef" @click="$emit('shrink')"></div>
<div class="video-element__play-button" @click="play()"></div>
</div>
</template>
<script>
import {ref, onMounted} from 'vue';
import Player from '@vimeo/player';
export default {
name: 'VideoPlayer',
setup() {
let player;
let isPlaying = false;
const playerRef = ref(null);
onMounted(() => {
const options = {
url: 'https://vimeo.com/393632283',
loop: false,
controls: false,
muted: true,
};
player = new Player(playerRef.value, options);
});
const play = () => {
player.play()
.then(isPlaying = true)
.catch(e => console.log(e));
};
const pause = () => {
player.pause()
isPlaying = false
};
return {
player, isPlaying, playerRef, play, pause
}
}
}
</script>
上面的代码已经过测试并按预期工作。
您可以查看 Template Refs for more information how to access HTML element inside setup()
. Regarding the setup()
method itself, please check the Composition API 文档。
此外,还有一些 Vimeo SDK 的 Vue 包装器,例如vue-vimeo-player
。如果你愿意,你可以使用它们而不是自己编写。
即使 Triet Doan 的回答现在被接受了,我也不喜欢它。它需要在 Options API 中编写的整个 OP 代码并将其重写为 Composition API 而没有解释为什么需要它...
嗯,根本不需要!事实上,最简单的修复原始代码的方法是在 data()
中注释掉 player: null
(如下面的演示所示)
为什么
Vue 的反应性可能有点打扰。使用 Object.defineProperty() (used for reactivity in Vue 2) and proxies 创建的 getters/setters (用于 Vue 3 中的反应性)都可以改变行为,特别是对于复杂数据 types/classes,就像 Vimeo Player 一样。
要解决此类问题,请不要将此类复杂对象放入 data()
或不要将它们包装在 ref()
或 reactive()
中。在大多数情况下,无论如何,您不需要 Vue 模板对此类复杂对象的某些内部状态作出反应....
而是将它们添加到实例中作为 this.player = new ...
in mounted
hook 或将它们声明为普通变量(没有 ref()
或 reactive()
)在 setup()
const app = Vue.createApp({
name: 'VideoPlayer',
data() {
return {
// player: null, <-- THIS LITTLE CHANGE IS NEEDED
}
},
mounted() {
this.initPlayer()
},
methods: {
async play() {
try {
await this.player.play()
this.isPlaying = true
} catch (e) {
console.log(e)
}
},
pause() {
this.player.pause()
this.isPlaying = false
},
initPlayer() {
let options = {
url: 'https://vimeo.com/393632283',
loop: false,
controls: false,
muted: true,
};
let element = this.$refs.player
this.player = new Vimeo.Player(element, options);
}
}
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.2.2/dist/vue.global.js"></script>
<script src="https://player.vimeo.com/api/player.js"></script>
<div id="app">
<div class="video-element__container">
<div class="video-element__player" ref="player" @click="$emit('shrink')"></div>
<div class="video-element__play-button" @click="play()"></div>
</div>
</div>
警告
另一方面,我完全同意使用existing wrapper - vue-vimeo-player. Because it handles some edge cases and more importantly the unloading of the player when the component is destroyed. Without it, you are creating a memory leak in your app
的建议