@@ -402,15 +402,11 @@ export async function getLocalVideoInfo(id) {
402402 }
403403
404404 if ( info . streaming_data . dash_manifest_url ) {
405- let url = info . streaming_data . dash_manifest_url
406-
407- if ( url . includes ( '?' ) ) {
408- url += `&pot=${ encodeURIComponent ( contentPoToken ) } &mpd_version=7`
409- } else {
410- url += `${ url . endsWith ( '/' ) ? '' : '/' } pot/${ encodeURIComponent ( contentPoToken ) } /mpd_version/7`
411- }
412-
413- info . streaming_data . dash_manifest_url = url
405+ info . streaming_data . dash_manifest_url = await decipherDashManifestUrl (
406+ info . streaming_data . dash_manifest_url ,
407+ webInnertube . session . player ,
408+ contentPoToken
409+ )
414410 }
415411 }
416412
@@ -462,6 +458,49 @@ async function decipherFormats(formats, player) {
462458 }
463459}
464460
461+ /**
462+ * @param {string } url
463+ * @param {import('youtubei.js').Player } player
464+ * @param {string } poToken
465+ */
466+ async function decipherDashManifestUrl ( url , player , poToken ) {
467+ const urlObject = new URL ( url )
468+
469+ if ( urlObject . searchParams . size > 0 ) {
470+ urlObject . searchParams . set ( 'pot' , poToken )
471+ urlObject . searchParams . set ( 'mpd_version' , '7' )
472+
473+ return await player . decipher ( urlObject . toString ( ) )
474+ }
475+
476+ // Convert path params to query params
477+ const pathParts = urlObject . pathname
478+ . replace ( '/api/manifest/dash' , '' )
479+ . split ( '/' )
480+ . filter ( part => part . length > 0 )
481+
482+ urlObject . pathname = '/api/manifest/dash'
483+
484+ for ( let i = 0 ; i + 1 < pathParts . length ; i += 2 ) {
485+ urlObject . searchParams . set ( pathParts [ i ] , decodeURIComponent ( pathParts [ i + 1 ] ) )
486+ }
487+
488+ // decipher
489+ const deciphered = await player . decipher ( urlObject . toString ( ) )
490+
491+ // convert query parameters back to path parameters
492+ const decipheredUrlObject = new URL ( deciphered )
493+
494+ for ( const [ key , value ] of decipheredUrlObject . searchParams ) {
495+ decipheredUrlObject . pathname += `/${ key } /${ encodeURIComponent ( value ) } `
496+ }
497+
498+ decipheredUrlObject . search = ''
499+ decipheredUrlObject . pathname += `/pot/${ encodeURIComponent ( poToken ) } /mpd_version/7`
500+
501+ return decipheredUrlObject . toString ( )
502+ }
503+
465504export async function getLocalChannelId ( url ) {
466505 try {
467506 const innertube = await createInnertube ( )
0 commit comments