diff --git a/examples/standalone/main.ts b/examples/standalone/main.ts index 40fc75db..59a0ebc3 100644 --- a/examples/standalone/main.ts +++ b/examples/standalone/main.ts @@ -107,6 +107,19 @@ const player = Player.make('#player', { new PlaylistPlugin({ initialIndex, sources: [ + { + title: 'HLS with SRT subtitle', + src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', + poster: 'https://api.imlazy.ink/img?id19', + subtitles: [ + { + name: 'Default', + src: SRT, + offset: 2 + } + ], + duration: '10:34' + }, { title: '君の名は - MP4', poster: POSTER, @@ -132,20 +145,6 @@ const player = Player.make('#player', { ], highlights: highlight }, - { - title: 'HLS with default SRT subtitle', - src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', - poster: 'https://api.imlazy.ink/img?id19', - subtitles: [ - { - name: 'Default', - default: true, - src: SRT, - offset: 2 - } - ], - duration: '10:34' - }, { title: 'BROKEN SOURCE & POSTER', src: '//', @@ -222,7 +221,7 @@ render(actions(), document.getElementById('actions')!) player.on((e: PlayerEvent) => { render(actions(), document.getElementById('actions')!) - if ('timeupdate' == e.type || 'notice' === e.type) { + if ('timeupdate' == e.type || 'notice' === e.type || 'progress' === e.type) { return } diff --git a/packages/dash/README.md b/packages/dash/README.md index a2b29e5c..dfadb831 100644 --- a/packages/dash/README.md +++ b/packages/dash/README.md @@ -46,7 +46,6 @@ export type Active = ( export interface DashPluginOptions { matcher?: Matcher - active?: Active /** * config for dashjs * diff --git a/packages/dash/src/index.ts b/packages/dash/src/index.ts index b2b262a1..01d1ef5e 100644 --- a/packages/dash/src/index.ts +++ b/packages/dash/src/index.ts @@ -10,8 +10,6 @@ export type Active = (instance: MediaPlayerClass, library: typeof import('dashjs export interface DashPluginOptions { library?: string matcher?: Matcher - active?: Active - inactive?: Active /** * config for dashjs * @@ -66,7 +64,7 @@ class DashPlugin implements PlayerPlugin { instance?: MediaPlayerClass - options: RequiredPartial = { + options: RequiredPartial = { textControl: true, audioControl: true, qualityControl: true, @@ -98,11 +96,7 @@ class DashPlugin implements PlayerPlugin { this.instance = DashPlugin.library.MediaPlayer().create() const { player, instance } = this - const { config, active } = this.options - - if (active) { - active(instance, DashPlugin.library) - } + const { config } = this.options if (config) instance.updateSettings(config) instance.initialize($video, source.src, $video.autoplay) @@ -122,9 +116,7 @@ class DashPlugin implements PlayerPlugin { destroy() { if (this.instance) { - // prettier-ignore - const { player, instance, options: { inactive } } = this - if (inactive) inactive(instance, DashPlugin.library) + const { player, instance } = this if (player.context.ui?.setting) removeSetting(player) instance.destroy() } diff --git a/packages/docs/public/oplayer.html b/packages/docs/public/oplayer.html index 57607674..d2a8566b 100644 --- a/packages/docs/public/oplayer.html +++ b/packages/docs/public/oplayer.html @@ -185,7 +185,7 @@ - + @@ -395,7 +395,7 @@ var prevTime = localStorage.getItem(e.payload.src) if (prevTime) { player.once('loadedmetadata', () => { - player.seek(prevTime) + player.seek(prevTime - 1) }) } } diff --git a/packages/hls/README.md b/packages/hls/README.md index 08a8ef3d..49531ab5 100644 --- a/packages/hls/README.md +++ b/packages/hls/README.md @@ -51,12 +51,6 @@ export type Active = ( export interface HlsPluginOptions { matcher?: Matcher - /** - * active or inactive(returned fn) - * - * @type {Active} - */ - active?: Active /** * config for hls.js * diff --git a/packages/hls/package.json b/packages/hls/package.json index b37c1b59..ba9b49d5 100644 --- a/packages/hls/package.json +++ b/packages/hls/package.json @@ -1,6 +1,6 @@ { "name": "@oplayer/hls", - "version": "1.2.26-beta.2", + "version": "1.2.26-beta.3", "description": "Hls plugin for oplayer", "type": "module", "main": "./dist/index.es.js", diff --git a/packages/hls/src/index.ts b/packages/hls/src/index.ts index 7e7c88ac..000bddc2 100644 --- a/packages/hls/src/index.ts +++ b/packages/hls/src/index.ts @@ -20,14 +20,6 @@ export interface HlsPluginOptions { * @returns {boolean} */ errorHandler?: (player: Player, data: ErrorData, cb: typeof defaultErrorHandler) => void - /** - * active - * - * @type {Active} - */ - active?: Active - - inactive?: Active /** * config for hls.js * @@ -79,11 +71,9 @@ const defaultMatcher: Matcher = (video, source, forceHLS) => { } const defaultErrorHandler = (player: Player, data: ErrorData) => { - if (data.fatal) { - const { type, details } = data - player.hasError = true - player.emit('error', { ...data, pluginName: PLUGIN_NAME, message: type + ': ' + details }) - } + const { type, details } = data + player.hasError = true + player.emit('error', { ...data, pluginName: PLUGIN_NAME, message: type + ': ' + details }) } class HlsPlugin implements PlayerPlugin { @@ -97,7 +87,7 @@ class HlsPlugin implements PlayerPlugin { instance?: Hls - options: RequiredPartial = { + options: RequiredPartial = { config: {}, forceHLS: false, textControl: true, @@ -131,16 +121,13 @@ class HlsPlugin implements PlayerPlugin { if (!HlsPlugin.library.isSupported()) return false - const { config, active, errorHandler } = this.options + const { config, errorHandler } = this.options this.instance = new HlsPlugin.library(config) + this.instance.attachMedia($video) const { instance, player } = this - if (active) { - active(instance, HlsPlugin.library) - } - const $source = document.createElement('source') $source.setAttribute('src', source.src) $source.setAttribute('type', source.type || (source.type = 'application/x-mpegurl')) @@ -152,11 +139,26 @@ class HlsPlugin implements PlayerPlugin { }) instance.on(HlsPlugin.library.Events.ERROR, function (_, data) { - errorHandler(player, data, defaultErrorHandler) + if (data.fatal) { + switch (data.type) { + case 'mediaError': + instance.recoverMediaError() + break + case 'networkError': + default: + errorHandler(player, data, defaultErrorHandler) + break + } + } + }) + + instance.on(HlsPlugin.library.Events.LEVEL_LOADED, (_, data) => { + setTimeout(() => { + player.emit('canplay', data) + }) }) instance.loadSource(source.src) - instance.attachMedia($video) if (player.context.ui?.setting) { generateSetting(player, instance, this.options) @@ -171,9 +173,7 @@ class HlsPlugin implements PlayerPlugin { destroy() { if (this.instance) { - // prettier-ignore - const { player, instance, options: { inactive } } = this - if (inactive) inactive(instance, HlsPlugin.library) + const { player, instance } = this if (player.context.ui?.setting) removeSetting(player) instance.destroy() } @@ -189,8 +189,8 @@ export default function create(options?: HlsPluginOptions): PlayerPlugin { const generateSetting = (player: Player, instance: Hls, options: HlsPluginOptions = {}) => { const ui = player.context.ui if (options.qualityControl) { - instance.once(HlsPlugin.library!.Events.MANIFEST_PARSED, () => { - settingUpdater({ + instance.once(HlsPlugin.library.Events.LEVEL_LOADED, () => { + injectSetting({ icon: ui.icons.quality, name: 'Quality', settings() { @@ -226,7 +226,7 @@ const generateSetting = (player: Player, instance: Hls, options: HlsPluginOption }) instance.on( - HlsPlugin.library!.Events.LEVEL_SWITCHED, + HlsPlugin.library.Events.LEVEL_SWITCHED, function menuUpdater(_, { level }: LevelSwitchedData) { if (instance.autoLevelEnabled) { const height = instance.levels[level]!.height @@ -240,8 +240,8 @@ const generateSetting = (player: Player, instance: Hls, options: HlsPluginOption } if (options.audioControl) - instance.on(HlsPlugin.library!.Events.AUDIO_TRACK_LOADED, () => { - settingUpdater({ + instance.on(HlsPlugin.library.Events.LEVEL_LOADED, () => { + injectSetting({ icon: ui.icons.lang, name: 'Language', settings() { @@ -261,8 +261,8 @@ const generateSetting = (player: Player, instance: Hls, options: HlsPluginOption }) if (options.textControl) - instance.on(HlsPlugin.library!.Events.SUBTITLE_TRACK_LOADED, () => { - settingUpdater({ + instance.on(HlsPlugin.library.Events.SUBTITLE_TRACK_LOADED, () => { + injectSetting({ icon: ui.icons.subtitle, name: 'Subtitle', settings() { @@ -289,7 +289,7 @@ const generateSetting = (player: Player, instance: Hls, options: HlsPluginOption }) }) - function settingUpdater(arg: { + function injectSetting(arg: { icon: string name: string settings: () => { name: string; default: boolean; value: any }[] | void