Fix legacy streams being closed early because they look idle

This commit is contained in:
absidue 2022-02-27 12:28:09 +01:00
parent 771b15e09f
commit 026fa34fdb

View File

@ -274,6 +274,13 @@ export async function video_basic_info(url: string, options: InfoOptions = {}):
if (!upcoming) {
format.push(...(player_response.streamingData.formats ?? []));
format.push(...(player_response.streamingData.adaptiveFormats ?? []));
// get the formats for the android player for legacy videos
// fixes the stream being closed because not enough data
// arrived in time for ffmpeg to be able to extract audio data
if (parseAudioFormats(format).length === 0 && !options.htmldata) {
format = await getAndroidFormats(vid.videoId, cookieJar, body);
}
}
const LiveStreamData = {
isLive: video_details.live,
@ -373,6 +380,13 @@ export async function video_stream_info(url: string, options: InfoOptions = {}):
if (!upcoming) {
format.push(...(player_response.streamingData.formats ?? []));
format.push(...(player_response.streamingData.adaptiveFormats ?? []));
// get the formats for the android player for legacy videos
// fixes the stream being closed because not enough data
// arrived in time for ffmpeg to be able to extract audio data
if (parseAudioFormats(format).length === 0 && !options.htmldata) {
format = await getAndroidFormats(player_response.videoDetails.videoId, cookieJar, body);
}
}
const LiveStreamData = {
@ -639,6 +653,36 @@ async function acceptViewerDiscretion(
return { streamingData };
}
async function getAndroidFormats(videoId: string, cookieJar: { [key: string]: string }, body: string): Promise<any[]> {
const apiKey =
body.split('INNERTUBE_API_KEY":"')[1]?.split('"')[0] ??
body.split('innertubeApiKey":"')[1]?.split('"')[0] ??
DEFAULT_API_KEY;
const response = await request(`https://www.youtube.com/youtubei/v1/player?key=${apiKey}`, {
method: 'POST',
body: JSON.stringify({
context: {
client: {
clientName: 'ANDROID',
clientVersion: '16.49',
hl: 'en',
timeZone: 'UTC',
utcOffsetMinutes: 0
}
},
videoId: videoId,
playbackContext: { contentPlaybackContext: { html5Preference: 'HTML5_PREF_WANTS' } },
contentCheckOk: true,
racyCheckOk: true
}),
cookies: true,
cookieJar
});
return JSON.parse(response).streamingData.formats;
}
function getWatchPlaylist(response: any, body: any, url: string): YouTubePlayList {
const playlist_details = response.contents.twoColumnWatchNextResults.playlist.playlist;