Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[reposted] Apiplayer Issue #160

Open
RedFireMRT84 opened this issue Nov 20, 2024 · 5 comments
Open

[reposted] Apiplayer Issue #160

RedFireMRT84 opened this issue Nov 20, 2024 · 5 comments

Comments

@RedFireMRT84
Copy link

Greetings, I'm sorry for reposting this, I accidentally closed the other one, which is why I reposted this. I've released this project last night: https://github.com/RedFireMRT84/Liinback-v3
I have my own getVideo route on where it loads InnerTube's youtubei/player for Android, and extracts the values for a url of .googlevideo.com and gets the latest quality in mp4 format, downloads the file and converts to a WEBM format in vp8.

My getVideo route:

@app.route('/api/videos/get/<video_id>', methods=['GET'])
def getVideo(video_id):
    url = f'https://www.googleapis.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&videoId={video_id}'
    headers = {
        'Content-Type': 'application/json',
        'User-Agent': 'com.google.android.youtube/19.02.39 (Linux; U; Android 14) gzip'
    }
    payload = {
        "context": {
            "client": {
                "hl": "en",
                "gl": "US",
                "clientName": "ANDROID",
                "clientVersion": "19.02.39",
                "androidSdkVersion": 34,
                "mainAppWebInfo": {
                    "graftUrl": "/watch?v=" + video_id
                }
            }
        },
        "videoId": video_id
    }
    response = requests.post(url, headers=headers, json=payload)
    data = response.json()
    streaming_data = data.get('streamingData', {})
    formats = streaming_data.get('adaptiveFormats', []) + streaming_data.get('formats', [])
    for f in formats:
        if f.get('audioChannels') == 2 and f.get('mimeType').startswith('video/mp4'):
            video_url = f.get('url')
            if video_url:
                input_file = f'assets/videoplayback.mp4'
                output_file = f'assets/{video_id}.webm'
                if os.path.exists(output_file):
                    return send_from_directory(os.getcwd(), output_file, as_attachment=True)
                with requests.get(video_url, stream=True) as r:
                    with open(input_file, 'wb') as f:
                        for chunk in r.iter_content(chunk_size=8192):
                            f.write(chunk)
                if os.path.exists(input_file):
                    conversion_to_webm_command = ['ffmpeg', '-v', 'verbose', '-i', input_file, '-c:v', 'libvpx', '-b:v', '500k', '-cpu-used', '8', '-vf', 'scale=-1:360', '-c:a', 'libvorbis', '-b:a', '128k', output_file]
                    subprocess.run(conversion_to_webm_command)
                    return send_from_directory(os.getcwd(), output_file, as_attachment=True)
                else:
                    return jsonify({"error": "Failed to download the video"}), 500
    return jsonify({"error": "No video with audioChannels 2 found"}), 404

runs very fine without the apiplayer. But for the apiplayer if I do a video longer than 1:48 seconds, the conversion of the WEBM format gets corrupted most at the times and the apiplayer either crashes your Wii, crashes the Flash emulator itself by:
https://gbatemp.net/attachments/img_4810-1-jpg.471605/
Or the video plays but corrupted and skips durations of the video.
I really think that the apiplayer itself is causing the getVideo route to be like this on the apiplayer.
https://www.youtube.com/watch?v=LtKghUBFdHI

@ftde0
Copy link
Owner

ftde0 commented Nov 20, 2024

assuming you've got all the codec-related stuff right, do you have any instruction to "wait" out if a request is called multiple times?

you don't want 2 downloads and conversions going on at the same time. this was the reason FLV playback was sorta broken on yt2009 for the longest time.

yt2009's example for waiting out multiple sent requests:
9c2900f#diff-1fdf8a070322a7cc40777617e5a89b729417eff14d5888bdb8d5f4eea6c8918f

@RedFireMRT84
Copy link
Author

Does YouTube's (/youtubei/player) route even support WEBMs in VP8 format anymore?

@ftde0
Copy link
Owner

ftde0 commented Nov 21, 2024

they don't serve VP8 anymore, WEBMs provided by youtube are VP9

@RedFireMRT84
Copy link
Author

RedFireMRT84 commented Nov 22, 2024

I'm currently trying to figure out a way to get more than 100 videos in the /youtubei/browse?browseId=VL{playlistId} URL to display. My playlist for example has 150 videos. But when I went to loaded the url in my custom route, it only includes 100 videos instead of 150. I'm using the WEB client and the Windows user agent to load the api. Is there another way to get the full lists of videos instead of the maximum of 100 videos to display?

@ftde0
Copy link
Owner

ftde0 commented Nov 22, 2024

open the playlist in desktop youtube, scroll down until the next part renders. you'll see a request with a "continuation token", use that. the continuation token is in the first playlist videos request as the last item. repeat until you don't get a continuation token anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants