如何让 html5 播放器在没有源的情况下播放
How to make an html5 player play without a source
我正在构建一个多媒体播放器,需要在一个页面上控制多个 other 多媒体播放器。为了做到这一点,我想在页面底部有一个区域,其中包含一个媒体播放控制器(包括一个搜索栏),它将控制页面上的所有其他播放器。例如,当用户点击播放按钮时,页面上的所有其他播放器都会开始播放。
我想使用常规 video/audio 播放器,但我想要的不是播放真实内容,而是拥有控件,尤其是前进的搜索栏。不自己实现播放控件的原因是因为我想使用 video.js 插件的强大功能(比如时间轴上的事件标记)。
我已经设法显示 video.js 播放器 仅 带有播放控件。此外,我还设法设置了持续时间。问题是当我按下播放按钮或调用 player.play()
时播放器不播放。
这是因为播放器没有媒体源。 video.js 如果没有媒体源,本机播放器将无法播放。
现在,有没有办法在没有资源的情况下强制播放器播放?我可以让它认为它有一个吗?
谢谢,
图片也是一样的道理。如果您没有某些内容的图像,则需要有一个备份计划:占位符图像。
您可以对视频执行相同的操作。
最简单的解决方案是在您的项目目录中:
> placeholders
|-- fakeVideo_short.mp4
|-- fakeVideo-long.mp4
|-- fakeAudio.mp3
|-- ...
每当您的上部 媒体控制器 发现一个空播放器时,您可以为其提供一个占位符内容。
这是一个简单的解决方案,可以让您更快地专注于重要的事情:媒体控制器。
如何检测玩家是否需要占位符?
嗯 :
- 每当播放器 finishes/consumes 一些内容时,如果没有更多内容可用,您可以为其提供一个占位符。
- 在 app 的开头,如果玩家数量多于内容,您可以向空玩家提供空白内容(占位符)。
我找到了一个可行的解决方案。
同样 目的是让 video.js 的工作媒体控制器无需加载任何媒体内容,最重要的控制器是搜索栏。
我一直在玩 video.js 并试图在不加载任何媒体内容的情况下使搜索栏前进,发现调用 player.currentTime()
确实实际上更新 curretTime
内部成员但不更新 UI。
最终我发现为了使 video.js 更新 UI 我们需要触发 timeupdate
事件。
所以我决定实现一个假玩家,它可以控制所有其他玩家,并使用 video.js 玩家作为他的 UI(通过显示只有媒体控制和隐藏视频)。
假玩家需要使用提到的精确计时器 .
概念示例:
import videojs from 'video.js';
class MainMediaController {
public static readonly INTERVAL = 250;
protected _playerId: string;
protected _duration: number;
protected _mediaController: videojs.Player;
protected _childPlayers: videojs.Player[];
protected _currentTime: number;
private _interval: number;
private _intervalId: number;
constructor(playerId: string, recordingDuration: number, childPlayers: videojs.Player[]) {
this._playerId = playerId; // id of the player at the bottom of the page which will be served as the main timeline
this._duration = recordingDuration;
this._interval = MainMediaController.INTERVAL;
this._childPlayers = childPlayers;
this._currentTime = 0;
}
public async init() {
this._mediaController = videojs(this._playerId);
// await for ready state
await new Promise((resolve, reject) => {
this._mediaController.ready(() => {
resolve();
});
});
// set duration for a correct seek bar (longest.endTime - first.startTime)
this._mediaController.duration(this._duration);
}
public play(){
// update UI every 250ms
this._intervalId = setInterval(this.intervalStep.bind(this), this._interval);
for(let player of this._childPlayers){
player.play();
}
}
private intervalStep(){
this._currentTime += 0.250; // 250ms
this._mediaController.currentTime(this._currentTime);
this._mediaController.trigger("timeupdate"); // trigger() is accessible don't worry
}
public pause(){...}
public stop(){...}
public seek(){...}
}
该解决方案让我可以在没有视频的主时间轴中使用 video.js 插件!!
我正在构建一个多媒体播放器,需要在一个页面上控制多个 other 多媒体播放器。为了做到这一点,我想在页面底部有一个区域,其中包含一个媒体播放控制器(包括一个搜索栏),它将控制页面上的所有其他播放器。例如,当用户点击播放按钮时,页面上的所有其他播放器都会开始播放。
我想使用常规 video/audio 播放器,但我想要的不是播放真实内容,而是拥有控件,尤其是前进的搜索栏。不自己实现播放控件的原因是因为我想使用 video.js 插件的强大功能(比如时间轴上的事件标记)。
我已经设法显示 video.js 播放器 仅 带有播放控件。此外,我还设法设置了持续时间。问题是当我按下播放按钮或调用 player.play()
时播放器不播放。
这是因为播放器没有媒体源。 video.js 如果没有媒体源,本机播放器将无法播放。
现在,有没有办法在没有资源的情况下强制播放器播放?我可以让它认为它有一个吗?
谢谢,
图片也是一样的道理。如果您没有某些内容的图像,则需要有一个备份计划:占位符图像。
您可以对视频执行相同的操作。
最简单的解决方案是在您的项目目录中:
> placeholders
|-- fakeVideo_short.mp4
|-- fakeVideo-long.mp4
|-- fakeAudio.mp3
|-- ...
每当您的上部 媒体控制器 发现一个空播放器时,您可以为其提供一个占位符内容。
这是一个简单的解决方案,可以让您更快地专注于重要的事情:媒体控制器。
如何检测玩家是否需要占位符?
嗯 :
- 每当播放器 finishes/consumes 一些内容时,如果没有更多内容可用,您可以为其提供一个占位符。
- 在 app 的开头,如果玩家数量多于内容,您可以向空玩家提供空白内容(占位符)。
我找到了一个可行的解决方案。
同样 目的是让 video.js 的工作媒体控制器无需加载任何媒体内容,最重要的控制器是搜索栏。
我一直在玩 video.js 并试图在不加载任何媒体内容的情况下使搜索栏前进,发现调用 player.currentTime()
确实实际上更新 curretTime
内部成员但不更新 UI。
最终我发现为了使 video.js 更新 UI 我们需要触发 timeupdate
事件。
所以我决定实现一个假玩家,它可以控制所有其他玩家,并使用 video.js 玩家作为他的 UI(通过显示只有媒体控制和隐藏视频)。
假玩家需要使用提到的精确计时器
概念示例:
import videojs from 'video.js';
class MainMediaController {
public static readonly INTERVAL = 250;
protected _playerId: string;
protected _duration: number;
protected _mediaController: videojs.Player;
protected _childPlayers: videojs.Player[];
protected _currentTime: number;
private _interval: number;
private _intervalId: number;
constructor(playerId: string, recordingDuration: number, childPlayers: videojs.Player[]) {
this._playerId = playerId; // id of the player at the bottom of the page which will be served as the main timeline
this._duration = recordingDuration;
this._interval = MainMediaController.INTERVAL;
this._childPlayers = childPlayers;
this._currentTime = 0;
}
public async init() {
this._mediaController = videojs(this._playerId);
// await for ready state
await new Promise((resolve, reject) => {
this._mediaController.ready(() => {
resolve();
});
});
// set duration for a correct seek bar (longest.endTime - first.startTime)
this._mediaController.duration(this._duration);
}
public play(){
// update UI every 250ms
this._intervalId = setInterval(this.intervalStep.bind(this), this._interval);
for(let player of this._childPlayers){
player.play();
}
}
private intervalStep(){
this._currentTime += 0.250; // 250ms
this._mediaController.currentTime(this._currentTime);
this._mediaController.trigger("timeupdate"); // trigger() is accessible don't worry
}
public pause(){...}
public stop(){...}
public seek(){...}
}
该解决方案让我可以在没有视频的主时间轴中使用 video.js 插件!!