Forums

A question about yt-dlp

Good afternoon. I just have a question about yt-dlp running on Flask servers while serving them on subdomain.pythonanywhere.com, even if you buy some premium. I found out that yt-dlp doesn't work on data center ip servers. Before I buy some premium here, just to get yt-dlp running on the pythonanywhere server, does it work on there or did YouTube banned every single server that runs on pythonanywhere in order to avoid downloading or getting their stream urls?

:::python class GetVideo: itag = "43"

    def fetch(self, lang, country, videoId, videoFormat, oauthToken=None, length=None):
        itag = videoFormat
        cleanup()

        temp_dir = tempfile.gettempdir()
        output = os.path.join(temp_dir, f"{videoId}.webm")

        if os.path.exists(output):
            return self.sendFileRange(output, mime="video/webm")

        cookies = initCookies()
        mkv_path = self.downloadAsMkv(cookies, videoId)

        if not mkv_path:
            return Response("Failed to download video", status=500)

        return self.encodeVideo(mkv_path, output, itag)

    def downloadAsMkv(self, cookies, videoId):
        temp_dir = tempfile.gettempdir()
        mkv_path = os.path.join(temp_dir, f"{videoId}.mkv")

        if os.path.exists(mkv_path):
            return mkv_path

        url = f"https://www.youtube.com/watch?v={videoId}"

        cmd = [
            "yt-dlp",
            "-f", "bestvideo[height<=360]+bestaudio/best[height<=360]/best",
            "--merge-output-format", "mkv",
            "--cookies", cookies,
            "--no-warnings",
            "--no-playlist",
            "-o", mkv_path,
            url
        ]

        try:
            result = subprocess.run(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                timeout=120
            )

            if result.returncode != 0:
                print("yt-dlp download error:", result.stderr)
                return None

            if os.path.exists(mkv_path):
                return mkv_path

            return None

        except Exception as e:
            print("yt-dlp download failed:", e)
            return None

    def fetchStream(self, lang, country, videoId, oauthToken=None, type=0):
        now = time.time()

        base_dir = os.path.dirname(os.path.abspath(__file__))
        cookies = os.path.join(base_dir, "c.txt")

        if videoId in STREAM_CACHE:
            url, expiry = STREAM_CACHE[videoId]

            if now < expiry:
                return url
            else:
                del STREAM_CACHE[videoId]

        if type == 1:
            try:
                api_url = "https://www.youtube.com/youtubei/v1/player"

                payload = {
                    "context": {
                        "client": {
                            "clientName": "ANDROID",
                            "clientVersion": "18.11.34",
                            "hl": lang,
                            "gl": country
                        }
                    },
                    "videoId": videoId
                }

                headers = {
                    "Content-Type": "application/json",
                    "User-Agent": "com.google.android.youtube/18.11.34"
                }

                r = requests.post(
                    api_url,
                    json=payload,
                    headers=headers,
                    timeout=3
                )

                data = r.json()

                formats = (
                    data.get("streamingData", {}).get("formats", []) +
                    data.get("streamingData", {}).get("adaptiveFormats", [])
                )

                for f in formats:
                    if f.get("height", 999) <= 360 and "url" in f:
                        stream = f["url"]
                        STREAM_CACHE[videoId] = (stream, now + CACHE_TTL)
                        return stream

            except Exception as e:
                print("FAST API failed:", e)

        else:
            try:
                stream = self.fetchStreamCLI(cookies, videoId)

                if stream:
                    STREAM_CACHE[videoId] = (stream, now + CACHE_TTL)
                    return stream

            except Exception as e:
                print("yt-dlp CLI failed:", e)

        return None

Free accounts have restricted internet access and we support only official and public APIs for our allow-list. Paid accounts have no such restrictions. You can experiment after upgrading, and if you're not satisfied, there's 30 days refund "no questions asked" policy.