feat(xgplayer): 增加preProcessUrl配置用于url的前置处理

This commit is contained in:
hongqiongxing 2023-10-19 11:58:34 +08:00 committed by xiyuyizhi
parent 7c00010e67
commit 5e63174587
11 changed files with 82 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import Player, { SimplePlayer, Util } from '../../packages/xgplayer/src/index'
import { TextTrack } from '../../packages/xgplayer/src/index'
import { I18N } from '../../packages/xgplayer/src'
// import DynamicBg from '../../packages/xgplayer/src/plugins/dynamicBg'
import FlvPlugin from '../../packages/xgplayer-flv'
console.log('vconsole')
window.Util = Util
window.POS = {
@ -38,7 +39,27 @@ function init(index = 0, config = {}) {
}
window[p] = new Player({
id: 'video' + index,
url: "//www.douyin.com/aweme/v1/play/?aid=6383&app_name=aweme&channel=channel_pc_web&device_platform=web&did=0&file_id=97ed815d341b4c4b88f5d264735450cc&fp=verify_lnmx61oz_AneyEmbA_UvI5_4NM1_BLMc_v9cDQxS71aFu&is_play_url=1&line=0&referer=&sign=361458dae299e58346ad40d061e0012e&source=PackSourceEnum_AWEME_DETAIL&target=7282384131110014265&user_agent=Mozilla%2F5.0%20%28Macintosh%3B%20Intel%20Mac%20OS%20X%2010_15_7%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F117.0.0.0%20Safari%2F537.36&video_id=v0200fg10000ck83jpvog65j9apo1ilg&webid=7288986370838726203&downgrade_264=1",
preProcessUrl: (url, ext) => {
console.log('>>>preProcessUrl', url, ext)
return {
url: `${url}&_test=1111`
}
},
url: 'https://pull-flv-l6.douyincdn.com/stage/stream-690397027603578911_or4.flv?k=058df17bfe1ed26d&t=1698388820&abr_pts=-800&_session_id=037-202310201440198CE1B6BE66B69406971E',
// [
// {
// "src": "//v3-weba.douyinvod.com/2857500552e19f085d24189890ff0165/6530aa8d/video/tos/cn/tos-cn-ve-15c001-alinc2/o0X7ARiEIAgyNpMfjKiCiNN5ld7OPAAKBBQeQ6/?a=6383&ch=54&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=632&bt=632&cs=2&ds=4&ft=XzJ6BM06xxouhL.D1PD12lMg4-iGNbLm-WwaU_4nU5F5JNv7T&mime_type=video_mp4&qs=15&rc=aTZpZDY4ZTM8OjY7O2c6ZUBpajN1O3Q5cjk0azMzNGkzM0AvXmAxMi0vNmIxY2NiLmJjYSNmZm0yMmRzb2VgLS1kLS9zcw%3D%3D&btag=e00030000&dy_q=1697684296&l=20231019105815487318B77115DF00DA47"
// },
// {
// "src": "//v26-web.douyinvod.com/11e2b45b2c9e088a66bde701b0f1fddd/6530aa8d/video/tos/cn/tos-cn-ve-15c001-alinc2/o0X7ARiEIAgyNpMfjKiCiNN5ld7OPAAKBBQeQ6/?a=6383&ch=54&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=632&bt=632&cs=2&ds=4&ft=XzJ6BM06xxouhL.D1PD12lMg4-iGNbLm-WwaU_4nU5F5JNv7T&mime_type=video_mp4&qs=15&rc=aTZpZDY4ZTM8OjY7O2c6ZUBpajN1O3Q5cjk0azMzNGkzM0AvXmAxMi0vNmIxY2NiLmJjYSNmZm0yMmRzb2VgLS1kLS9zcw%3D%3D&btag=e00030000&dy_q=1697684296&l=20231019105815487318B77115DF00DA47"
// },
// {
// "src": "//www.douyin.com/aweme/v1/play/?video_id=v0200fg10000chh1r6vog65q58pri0ig&line=0&file_id=fbe71de8f8f347e9902b05534acfa32f&sign=fa5a42d741ad5527ddf70a7adbca6973&is_play_url=1&source=PackSourceEnum_MIX_AWEME&aid=6383"
// },
// {
// "src": "//www.douyin.com/aweme/v1/play/?aid=6383&app_name=aweme&channel=channel_pc_web&device_platform=web&did=0&file_id=455c603feba54fb1afc21cceac74023b&fp=verify_lnmx61oz_AneyEmbA_UvI5_4NM1_BLMc_v9cDQxS71aFu&is_play_url=1&line=0&referer=&sign=e64285bb554bbb89efb51eadad73322e&source=PackSourceEnum_MIX_AWEME&target=7233376372733775160&user_agent=Mozilla%2F5.0%20%28Macintosh%3B%20Intel%20Mac%20OS%20X%2010_15_7%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F118.0.0.0%20Safari%2F537.36&video_id=v0200fg10000chh1r6vog65q58pri0ig&webid=7288986370838726203&downgrade_264=1"
// }
// ],
DynamicBg: {
disable: false
},
@ -50,7 +71,7 @@ function init(index = 0, config = {}) {
preloadTime: 20,
width: '80%',
ignores:['playbackrate'],
plugins: [],
plugins: [FlvPlugin],
rotate: true,
// controls: {
// // mode: 'normal',

View File

@ -60,6 +60,7 @@ export class Flv extends EventEmitter {
timeout: this._opts.loadTimeout,
onRetryError: this._onRetryError,
onProgress: this._onProgress,
onPreProcessUrl: opts.preProcessUrl,
responseType: 'arraybuffer'
})
@ -95,6 +96,10 @@ export class Flv extends EventEmitter {
return !!this._keyframes && this._acceptRanges
}
get loader () {
return this._mediaLoader
}
speedInfo () {
return {
speed: this._bandwidthService.getLatestSpeed(),

View File

@ -16,7 +16,11 @@
* preloadTime?: number,
* disconnectTime?: number,
* fetchOptions?: RequestInit,
* seamlesslyReload: boolean
* seamlesslyReload: boolean,
* keepStatusAfterSwitch?: boolean,
* onlyVideo?: boolean,
* onlyAudio?: boolean,
* preProcessUrl?: (url: string, ext?: { [propName: string]: any }) => { url: string, [propName: string]: any }
* }} FlvOption
*/

View File

@ -32,6 +32,10 @@ export class FlvPlugin extends BasePlugin {
return !!mediaType && mediaType !== 'video' && mediaType !== 'audio'
}
get loader () {
return this.flv?.loader
}
beforePlayerInit () {
const config = this.player.config
@ -50,6 +54,7 @@ export class FlvPlugin extends BasePlugin {
softDecode: this.softDecode,
isLive: config.isLive,
media: this.player.video,
preProcessUrl: (url, ext) => this.player.preProcessUrl?.(url, ext) || {url, ext},
...flvOpts
})

View File

@ -10,6 +10,7 @@ export function getConfig (cfg) {
onTimeout: undefined,
onProgress: undefined,
onRetryError: undefined,
onPreProcessUrl: undefined,
transformRequest: undefined,
transformResponse: undefined,
transformError: undefined,

View File

@ -21,6 +21,8 @@ export class NetLoader extends EventEmitter {
_currentTask = null
_finnalUrl = ''
_config
constructor (cfg) {
@ -39,6 +41,10 @@ export class NetLoader extends EventEmitter {
return this.type === LoaderType.FETCH
}
get finnalUrl () {
return this._finnalUrl
}
static isFetchSupport () {
return FetchLoader.isSupported()
}
@ -51,6 +57,13 @@ export class NetLoader extends EventEmitter {
}
config = Object.assign({}, this._config, config)
if (this._config.onPreProcessUrl) {
config.url = this._config.onPreProcessUrl(config.url).url
}
this._finnalUrl = config.url
if (config.params) config.params = Object.assign({}, config.params)
if (config.headers && isPlainObject(config.headers)) config.headers = Object.assign({}, config.headers)
if (config.body && isPlainObject(config.body)) config.body = Object.assign({}, config.body)

View File

@ -1,8 +1,12 @@
import { getLang } from './utils/util'
/**
* @typedef { string | MediaStream | Array<{src: string, type?:string, [propName: string]: any}> } IUrl
*/
/**
* @typedef {{
* url: any,
* url: IUrl,
* definition: any,
* bitrate?: number,
* bandwidth?: number,
@ -16,7 +20,7 @@ import { getLang } from './utils/util'
* @typedef { {
* id?: string,
* el?: HTMLElement,
* url?: any,
* url?: IUrl,
* domEventType?: 'default' | 'touch' | 'mouse',
* nullUrlStart?: boolean,
* width?: number | string,
@ -53,6 +57,7 @@ import { getLang } from './utils/util'
* miniprogress?: boolean,
* disableSwipeHandler?: () => any,
* enableSwipeHandler?: () => any,
* preProcessUrl?: (url: IUrl, ext?: { [propName: string]: any }) => { url: IUrl, [propName: string]: any },
* ignores?: Array<'cssfullscreen' | 'screenshot' | 'pip' | 'miniscreen' | 'keyboard' | 'download' | 'playbackrate' | 'time' | 'definition' | 'error' | 'fullscreen' | 'loading' | 'mobile' | 'pc' | 'play' | 'poster' | 'progress' | 'replay' | 'start' | 'volume' | string>,
* inactive?: number,
* lang?: string,
@ -144,6 +149,7 @@ export default function getDefaultConfig () {
},
enableSwipeHandler: () => {
},
preProcessUrl: null, // url preprocessing callback
ignores: [], // list of plug-in names to be disabled
whitelist: [],
inactive: 3000, // delay time for the control bar to disappear automatically

View File

@ -750,7 +750,7 @@ class MediaProxy extends EventEmitter {
this._currentTime = 0
this._duration = 0
// Some firefox versions firefox Cannot recognize currentSrc of type Blob
if (/^blob/.test(this.media.currentSrc) || /^blob/.test(this.media.src)) { // has transmuxer core
if (Util.isMSE(this.media)) {
this.onWaiting()
return
}

View File

@ -24,6 +24,7 @@ import { STATES, STATE_ARRAY } from './state'
/**
* @typedef { import ('./defaultConfig').IDefinition } IDefinition
* @typedef { import ('./defaultConfig').IUrl } IUrl
*/
/* eslint-disable camelcase */
@ -580,8 +581,7 @@ class Player extends MediaProxy {
const { readyState } = this.media
XG_DEBUG.logInfo('_startInit readyState', readyState)
if (this.config.autoplay) {
!(/^blob/.test(this.media.currentSrc) || /^blob/.test(this.media.src)) &&
this.load();
!Util.isMSE(this.media) && this.load()
// ios端无法自动播放的场景下不调用play不会触发canplay loadeddata等事件
(Sniffer.os.isIpad || Sniffer.os.isPhone) && this.mediaPlay()
}
@ -897,7 +897,8 @@ class Player extends MediaProxy {
if (!url) {
url = this.url || this.config.url
}
const ret = this._startInit(url)
const _furl = this.preProcessUrl(url)
const ret = this._startInit(_furl.url)
return ret
})
.catch((e) => {
@ -922,6 +923,7 @@ class Player extends MediaProxy {
if (Util.typeOf(url) === 'Object') {
_src = url.url
}
_src = this.preProcessUrl(_src).url
const curTime = this.currentTime
const isPaused = this.paused && !this.isError
this.src = _src
@ -2200,6 +2202,17 @@ class Player extends MediaProxy {
this._state = newState
}
/**
* @description url preprocessing
* @param { IUrl } url
* @param { {[propName: string]: any} } [ext]
* @returns { url: IUrl, [propName: string]: any }
*/
preProcessUrl (url, ext) {
const { preProcessUrl } = this.config
return !Util.isBlob(url) && preProcessUrl && typeof preProcessUrl === 'function' ? preProcessUrl(url, ext) : { url }
}
/**
* @type { number }
*/

View File

@ -227,7 +227,7 @@ class DynamicBg extends Plugin {
return null
}
const _tVideo = video && video instanceof window.HTMLVideoElement ? video : (video.canvas ? video.canvas : (video.flyVideo ? video.flyVideo : null))
if (_tVideo && !(Sniffer.browser === 'safari' && (/^blob/.test(_tVideo.currentSrc) || /^blob/.test(_tVideo.src)))) {
if (_tVideo && !(Sniffer.browser === 'safari' && Util.isMSE(_tVideo))) {
return _tVideo
}

View File

@ -778,6 +778,10 @@ util.isMSE = function (video) {
return /^blob/.test(video.currentSrc) || /^blob/.test(video.src)
}
util.isBlob = function (url) {
return /^blob/.test(url)
}
/**
* @param { number } did
* @returns { string }