analitics

Pages

Thursday, May 7, 2026

Python Qt : simple tiktok downloader.

Today, simple example with PyQt6 and yt_dlp.
Get the link from tiktok browser and use it to download the video for your storage.
I used the Copilot tool. It seems to know the Romanian language. For a developer, comments and source code are not an impediment, because it is very simplistic.
Let's see the source code:
import sys
import os
import yt_dlp
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
    QLineEdit, QLabel, QFileDialog, QListWidget, QListWidgetItem,
    QProgressBar, QMessageBox
)
from PyQt6.QtCore import Qt

class TikTokDownloader(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("TikTok Downloader (yt-dlp)")
        self.setMinimumWidth(600)

        self.url_input = QLineEdit()
        self.url_input.setPlaceholderText("Introdu URL TikTok...")

        self.folder_input = QLineEdit()
        self.folder_input.setPlaceholderText("Folder download...")

        browse_btn = QPushButton("Selectează folder")
        browse_btn.clicked.connect(self.select_folder)

        fetch_btn = QPushButton("Caută stream-uri")
        fetch_btn.clicked.connect(self.fetch_streams)

        self.stream_list = QListWidget()

        download_btn = QPushButton("Descarcă")
        download_btn.clicked.connect(self.download_selected)

        self.progress = QProgressBar()
        self.progress.setValue(0)

        layout = QVBoxLayout()
        layout.addWidget(QLabel("URL TikTok:"))
        layout.addWidget(self.url_input)

        folder_layout = QHBoxLayout()
        folder_layout.addWidget(self.folder_input)
        folder_layout.addWidget(browse_btn)
        layout.addLayout(folder_layout)

        layout.addWidget(fetch_btn)
        layout.addWidget(QLabel("Stream-uri găsite:"))
        layout.addWidget(self.stream_list)
        layout.addWidget(download_btn)
        layout.addWidget(self.progress)

        self.setLayout(layout)

        self.streams = []
        self.selected_format = None

    def select_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "Selectează folder")
        if folder:
            self.folder_input.setText(folder)

    def fetch_streams(self):
        url = self.url_input.text().strip()
        if not url:
            QMessageBox.warning(self, "Eroare", "Introdu URL TikTok")
            return

        self.stream_list.clear()
        self.streams = []

        ydl_opts = {
            "quiet": True,
            "skip_download": True,
            "forcejson": True,
        }

        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                info = ydl.extract_info(url, download=False)

            formats = info.get("formats", [])

            for f in formats:
                desc = f"{f.get('format_id')} | {f.get('ext')} | {f.get('resolution', '')} | {f.get('filesize', 'N/A')}"
                item = QListWidgetItem(desc)
                self.stream_list.addItem(item)
                self.streams.append(f)

        except Exception as e:
            QMessageBox.critical(self, "Eroare", str(e))

    def progress_hook(self, d):
        if d["status"] == "downloading":
            if d.get("total_bytes"):
                pct = int(d["downloaded_bytes"] * 100 / d["total_bytes"])
                self.progress.setValue(pct)

        if d["status"] == "finished":
            self.progress.setValue(100)

    def download_selected(self):
        folder = self.folder_input.text().strip()
        if not folder:
            QMessageBox.warning(self, "Eroare", "Selectează folderul de download")
            return

        selected = self.stream_list.currentRow()
        if selected < 0:
            QMessageBox.warning(self, "Eroare", "Selectează un stream din listă")
            return

        fmt = self.streams[selected]
        url = self.url_input.text().strip()

        ydl_opts = {
            "outtmpl": os.path.join(folder, "%(id)s.%(ext)s"),
            "format": fmt["format_id"],
            "progress_hooks": [self.progress_hook],
        }

        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                ydl.download([url])

            QMessageBox.information(self, "Succes", "Download complet!")

        except Exception as e:
            QMessageBox.critical(self, "Eroare", str(e))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = TikTokDownloader()
    win.show()
    sys.exit(app.exec())