Skip to content

Commit

Permalink
[Feature]Playlist plugin works together with hls plugin #102 (#104)
Browse files Browse the repository at this point in the history
* [Feature Request]Playlist plugin works together with hls plugin? #102
  • Loading branch information
shiyiya authored Oct 31, 2023
1 parent ff24cc5 commit 87707cc
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 51 deletions.
20 changes: 18 additions & 2 deletions examples/standalone/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { html, render } from 'lit'
import { live } from 'lit/directives/live.js'
import { ref } from 'lit/directives/ref.js'

import { Player, isMobile, PlayerEvent } from '@oplayer/core'
import { Player, isMobile, PlayerEvent, Source } from '@oplayer/core'
import danmaku from '@oplayer/danmaku'
import dash from '@oplayer/dash'
import hls from '@oplayer/hls'
Expand Down Expand Up @@ -108,7 +108,23 @@ const player = Player.make<Ctx>('#player', {
new Hello(),
new PlaylistPlugin({
initialIndex: 0,
m3uList: {
sourceFormat(info) {
const chunk = info.title.substring(3).split(' ')
const titleWith = chunk.find(it => it.includes('title')).split('=')[1]
const posterWith = chunk.find(it => it.includes('logo'))?.split('=')[1]
return {
src: info.uri,
format: 'm3u8',
title: titleWith.substring(1, titleWith.length),
poster: posterWith?.substring(1, posterWith.length),
}
},
},
sources: [
{
src: 'https://raw.githubusercontent.com/fanmingming/live/main/tv/m3u/global.m3u'
},
{
title: '君の名は - MP4',
poster: POSTER,
Expand Down Expand Up @@ -235,7 +251,7 @@ const actions = () => html`<p style="display:flex;">
]!
player.changeSource(
new Promise((r) => {
new Promise<Source>((r) => {
stopLoad()
r({ src })
})
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@babel/plugin-transform-template-literals": "^7.22.5",
"@changesets/cli": "^2.26.2",
"@rollup/plugin-babel": "^6.0.4",
"@types/node": "^18.18.6",
"@types/node": "^18.18.7",
"@vitejs/plugin-react": "^4.1.0",
"babel-plugin-syntax-trailing-function-commas": "^6.22.0",
"concurrently": "^8.2.2",
Expand Down
5 changes: 3 additions & 2 deletions packages/plugins/build-plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { globSync } from 'glob'
import chokidar from 'chokidar'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'

const external = ['@oplayer/core']
const external = ['@oplayer/core', 'm3u8-parser']

const globals = {
'@oplayer/core': 'OPlayer'
'@oplayer/core': 'OPlayer',
'm3u8-parser': 'm3u8Parser'
}

async function buildPlugin(name, dev) {
Expand Down
5 changes: 3 additions & 2 deletions packages/plugins/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oplayer/plugins",
"version": "1.0.8",
"version": "1.0.9-playlist.0",
"description": "oplayer's plugin",
"type": "module",
"main": "dist/index.es.js",
Expand All @@ -18,7 +18,8 @@
"@types/chromecast-caf-sender": "^1.0.7",
"chokidar": "^3.5.3",
"glob": "^10.3.10",
"vite-plugin-css-injected-by-js": "^3.3.0"
"vite-plugin-css-injected-by-js": "^3.3.0",
"m3u8-parser": "^7.1.0"
},
"keywords": [],
"author": "",
Expand Down
63 changes: 53 additions & 10 deletions packages/plugins/src/playlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,23 @@ interface Ctx {
ui: UIInterface
}

interface Segment {
uri: string
timeline: number
title: string
}

export interface PlaylistOptions {
sources: PlaylistSource[]
customFetcher?: (source: PlaylistSource, index: number) => Promise<PlaylistSource> | PlaylistSource
autoNext?: boolean
autoHide?: boolean
initialIndex?: number
m3uList?:
| {
sourceFormat?: (info: Segment) => Source
}
| true
}

export interface PlaylistSource extends Omit<Source, 'src'> {
Expand All @@ -28,6 +39,9 @@ export default class PlaylistPlugin implements PlayerPlugin {
name = 'oplayer-plugin-playlist'
version = __VERSION__

//@ts-expect-error
static m3u8Parser = globalThis.m3u8Parser

player!: Player<Ctx>

currentIndex?: number
Expand All @@ -44,21 +58,50 @@ export default class PlaylistPlugin implements PlayerPlugin {
if (player.isNativeUI) return

this.player = player as Player<Ctx>
this.render()

const { autoNext, initialIndex } = this.options
this._init()

if (autoNext) {
this.player.on('ended', () => {
this.next()
})
}
return this
}

if (typeof initialIndex == 'number') {
this.changeSource(initialIndex)
async _init() {
const start = () => {
this.render()
if (typeof initialIndex == 'number') {
this.changeSource(initialIndex)
}
if (this.options.autoNext) {
this.player.on('ended', () => {
this.next()
})
}
}

return this
const { initialIndex, m3uList, sources } = this.options

if (m3uList && sources[0]?.src) {
//@ts-ignore
if (!PlaylistPlugin.m3u8Parser) PlaylistPlugin.m3u8Parser = await import('m3u8-parser')
fetch(sources[0].src)
.then((resp) => resp.text())
.then((manifest) => {
const parser = new PlaylistPlugin.m3u8Parser.Parser()
parser.push(manifest)
parser.end()
this.options.sources = parser.manifest.segments.map((seg: Segment) => {
if ((<any>m3uList)?.sourceFormat) {
return (<any>m3uList).sourceFormat(seg)
}
return { src: seg.uri, title: seg.title }
})
start()
})
.catch((err) => {
this.player.emit('notice', { pluginName: this.name, text: 'Playlist' + (<Error>err).message })
})
} else {
start()
}
}

get isWaiting() {
Expand Down
Loading

1 comment on commit 87707cc

@vercel
Copy link

@vercel vercel bot commented on 87707cc Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

oplayer – ./

oplayer.vercel.app
oplayer-shiyiya.vercel.app
oplayer-git-main-shiyiya.vercel.app

Please sign in to comment.