Çözüldü Python PyCharm'da YT-DLP kütüphanesi eklenmiyor

Bu konu çözüldü olarak işaretlenmiştir. Çözülmediğini düşünüyorsanız konuyu rapor edebilirsiniz.

Daiquiri

Hectopat
Katılım
8 Haziran 2022
Mesajlar
1.407
Çözümler
12
YT-DLP kullanarak bir program yazdım. Düne kadar bir sorun yoktu ama dün EXE dosyasına çevirince YT-DLP kütüphanesi EXE'ye dahil edilmedi. PyCharm'da paketler kısmına baktım YT-DLP dokümantasyon sayfası da açılmıyor. Diğer paketlerin dokümantasyon sayfası geliyor ve onlar EXE'ye çevirirken projeye de dahil ediliyor, onlarda bir sorun yok. YT-DLP'yi kaldırdım, yükledim, olmadı. Eski sürümü kurdum, yine olmadı. Örnek olması açısından pip ve YT-DLP'nin bölümlerinin fotoğrafını bırakıyorum. Gördüğünüz gibi YT-DLP'yi seçince herhangi bir şey gözükmüyor. Çözüm önerisi olan var mı? (Pycharm 2025.1)

1745220785364.png


1745220807579.png
 
Çözüm
Python:
pyinstaller --onefile --hidden-import=yt_dlp --collect-submodules=yt_dlp --collect-data=yt_dlp scriptin.py

Python:
import yt_dlp

Bu bu sıra ile tekrar deneyebilir misin acaba?

Büyük ihtimalle sen alttakini yazdın. Benim yazdığım daha garanti.
Python:
pyinstaller --onefile --hidden-import=yt_dlp your_script.py

Yanlış anlama bende yeni başlamış sayılırım. Aklıma bu geldi. Eğer yine işe yaramazsa .spec dosyasını düzenle. Bende fikir tükendi.
İşe yaramadı spec'i de denedim.

YT-DLP kullanarak bir program yazdım. Düne kadar bir sorun yoktu ama dün EXE dosyasına çevirince YT-DLP kütüphanesi EXE'ye dahil edilmedi. PyCharm'da paketler kısmına baktım YT-DLP dokümantasyon sayfası da açılmıyor. Diğer paketlerin dokümantasyon sayfası geliyor ve onlar EXE'ye çevirirken projeye de dahil ediliyor, onlarda bir sorun yok. YT-DLP'yi kaldırdım, yükledim, olmadı. Eski sürümü kurdum, yine olmadı. Örnek olması açısından pip ve YT-DLP'nin bölümlerinin fotoğrafını bırakıyorum. Gördüğünüz gibi YT-DLP'yi seçince herhangi bir şey gözükmüyor. Çözüm önerisi olan var mı? (PyCharm 2025.1)

Eki Görüntüle 2474624

Eki Görüntüle 2474625

Sorun çözüldü. Yeni bir Python interpreter oluşturdum. YT-DLP dokümantasyon sayfası yine gözükmüyor ama EXE'ye otomatik olarak dahil ediyor. EXE'ye çevirince sorunsuz çalışıyor.
YT-DLP kullanarak bir program yazdım. Düne kadar bir sorun yoktu ama dün EXE dosyasına çevirince YT-DLP kütüphanesi EXE'ye dahil edilmedi. PyCharm'da paketler kısmına baktım YT-DLP dokümantasyon sayfası da açılmıyor. Diğer paketlerin dokümantasyon sayfası geliyor ve onlar EXE'ye çevirirken projeye de dahil ediliyor, onlarda bir sorun yok. YT-DLP'yi kaldırdım, yükledim, olmadı. Eski sürümü kurdum, yine olmadı. Örnek olması açısından pip ve YT-DLP'nin bölümlerinin fotoğrafını bırakıyorum. Gördüğünüz gibi YT-DLP'yi seçince herhangi bir şey gözükmüyor. Çözüm önerisi olan var mı? (PyCharm 2025.1)

Eki Görüntüle 2474624

Eki Görüntüle 2474625

Dostum, benim de projem var, kendi halimde kullanıyorum. İstersen atayım, kendin örnek al. Ben direkt YT-DLP’yi EXE olarak dizindeki "datas" klasörüne koydum, klasörü de projeye dahil ettim. EXE’ye çevirirken onları da kapsıyor, içine alıyor. Pek yardımcı olamadım fakat ufak da bir yardımı dokunur belki, kodu çalabilirsin, sorun yok.

Kod:
import sys
import os
import re
import json
import subprocess
from pathlib import Path
from PyQt6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, QLabel,
 QLineEdit, QFileDialog, QComboBox, QTextEdit, QGridLayout,
 QCheckBox, QMessageBox, QProgressBar, QGroupBox,
 QTabWidget, QHBoxLayout, QInputDialog)
from PyQt6.QtCore import Qt, QSize, QProcess
from PyQt6.QtGui import QIcon, QPixmap, QColor, QTextCursor, QPalette

class FastweXDownloader(QWidget):
 def __init__(self):
 super().__init__()
 self.setup_paths()
 try:
 self.check_dependencies()
 except Exception as e:
 QMessageBox.critical(self, "Hata", f"Başlatma hatası:\n{str(e)}")
 sys.exit(1)

 self.setWindowTitle("FastweX İndirici v4.0")
 self.setWindowIcon(QIcon(self.logo_path))
 self.setGeometry(100, 100, 900, 800)
 self.setup_ui_theme()
 self.init_ui()
 self.load_config()

 def setup_ui_theme(self):
 """Modern dark theme setup"""
 palette = QPalette()

 # Base colors
 palette.setColor(QPalette.ColorRole.Window, QColor(45, 45, 48))
 palette.setColor(QPalette.ColorRole.WindowText, QColor(240, 240, 240))
 palette.setColor(QPalette.ColorRole.Base, QColor(30, 30, 30))
 palette.setColor(QPalette.ColorRole.AlternateBase, QColor(45, 45, 48))
 palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(53, 53, 53))
 palette.setColor(QPalette.ColorRole.ToolTipText, Qt.GlobalColor.white)
 palette.setColor(QPalette.ColorRole.Text, QColor(240, 240, 240))
 palette.setColor(QPalette.ColorRole.Button, QColor(63, 63, 70))
 palette.setColor(QPalette.ColorRole.ButtonText, QColor(240, 240, 240))
 palette.setColor(QPalette.ColorRole.BrightText, Qt.GlobalColor.red)
 palette.setColor(QPalette.ColorRole.Highlight, QColor(0, 122, 204))
 palette.setColor(QPalette.ColorRole.HighlightedText, Qt.GlobalColor.white)

 self.setPalette(palette)

 self.setStyleSheet("""
 /* GENERAL STYLES */
 QWidget {
 font-family: 'Segoe UI', Arial, sans-serif;
 font-size: 12px;
 color: #f0f0f0;
 }

 /* GROUP BOXES */
 QGroupBox {
 border: 1px solid #3e3e42;
 border-radius: 6px;
 margin-top: 10px;
 padding-top: 15px;
 background-color: #2d2d30;
 }
 QGroupBox::title {
 subcontrol-origin: margin;
 left: 10px;
 padding: 0 5px;
 color: #f0f0f0;
 }

 /* BASIC BUTTONS */
 QPushButton {
 background-color: #3e3e42;
 border: 1px solid #3e3e42;
 border-radius: 4px;
 padding: 6px 12px;
 min-width: 80px;
 color: #f0f0f0;
 }
 QPushButton:hover {
 background-color: #4e4e52;
 border-color: #5e5e62;
 }
 QPushButton:pressed {
 background-color: #2d2d30;
 }

 /* SPECIAL BUTTONS */
 QPushButton#download_button {
 background-color: #007acc;
 color: white;
 font-weight: bold;
 border: 1px solid #006bb3;
 font-size: 14px;
 height: 40px;
 padding-left: 20px;
 padding-right: 20px;
 }
 QPushButton#download_button:hover {
 background-color: #006bb3;
 }
 QPushButton#download_button:pressed {
 background-color: #005a9c;
 }

 QPushButton#browse_button, QPushButton#insta_browse_button {
 background-color: #68217a;
 color: white;
 border: 1px solid #5a1b6a;
 }
 QPushButton#browse_button:hover, QPushButton#insta_browse_button:hover {
 background-color: #5a1b6a;
 }

 QPushButton#add_url_button, QPushButton#load_txt_button {
 background-color: #d35400;
 color: white;
 border: 1px solid #b34700;
 }
 QPushButton#add_url_button:hover, QPushButton#load_txt_button:hover {
 background-color: #b34700;
 }

 QPushButton#clear_urls_button {
 background-color: #e51400;
 color: white;
 border: 1px solid #c41200;
 }
 QPushButton#clear_urls_button:hover {
 background-color: #c41200;
 }

 /* OTHER ELEMENTS */
 QLineEdit, QTextEdit, QComboBox {
 border: 1px solid #3e3e42;
 border-radius: 4px;
 padding: 5px;
 background-color: #252526;
 color: #f0f0f0;
 selection-background-color: #007acc;
 }
 QProgressBar {
 height: 20px;
 text-align: center;
 border: 1px solid #3e3e42;
 border-radius: 4px;
 background-color: #252526;
 }
 QProgressBar::chunk {
 background-color: #007acc;
 width: 10px;
 }
 QTextEdit {
 background-color: #1e1e1e;
 color: #e0e0e0;
 font-family: Consolas;
 font-size: 10pt;
 border: 1px solid #3e3e42;
 border-radius: 4px;
 }
 QTabWidget::pane {
 border: 1px solid #3e3e42;
 border-radius: 4px;
 margin-top: 5px;
 background-color: #2d2d30;
 }
 QTabBar::tab {
 padding: 8px 12px;
 background: #2d2d30;
 border: 1px solid #3e3e42;
 border-bottom: none;
 border-top-left-radius: 4px;
 border-top-right-radius: 4px;
 margin-right: 2px;
 color: #f0f0f0;
 }
 QTabBar::tab:selected {
 background: #252526;
 border-bottom: 1px solid #252526;
 margin-bottom: -1px;
 }
 QTabBar::tab:hover {
 background: #3e3e42;
 }

 /* CHECKBOX STYLE */
 QCheckBox {
 color: #f0f0f0;
 }
 QCheckBox::indicator {
 width: 16px;
 height: 16px;
 }
 QCheckBox::indicator:unchecked {
 background-color: #252526;
 border: 1px solid #3e3e42;
 }
 QCheckBox::indicator:checked {
 background-color: #007acc;
 border: 1px solid #006bb3;
 image: url(:/qss_icons/rc/checkbox_checked.png);
 }

 /* COMBOBOX STYLE */
 QComboBox::drop-down {
 border: none;
 }
 QComboBox::down-arrow {
 image: url(:/qss_icons/rc/down_arrow.png);
 }
 """)

 def setup_paths(self):
 self.base_dir = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
 self.data_dir = os.path.join(self.base_dir, "datas")
 self.downloads_path = str(Path.home() / "Downloads")
 self.logo_path = os.path.join(self.data_dir, "logo", "fastwex.png")
 self.yt_dlp_path = os.path.join(self.data_dir, "yt-dlp", "yt-dlp.exe")
 self.gallery_dl_path = os.path.join(self.data_dir, "gallery-dl", "gallery-dl.exe")
 self.ffmpeg_dir = os.path.join(self.data_dir, "ffmpeg-codec", "bin")
 self.ffmpeg_path = os.path.join(self.ffmpeg_dir, "ffmpeg.exe")
 self.config_path = os.path.join(self.base_dir, "config.json")

 os.makedirs(self.data_dir, exist_ok=True)
 os.makedirs(self.downloads_path, exist_ok=True)

 def check_dependencies(self):
 missing = []
 if not os.path.exists(self.yt_dlp_path):
 missing.append("yt-dlp.exe")
 if not os.path.exists(self.gallery_dl_path):
 missing.append("gallery-dl.exe")
 if not os.path.exists(self.ffmpeg_path):
 missing.append("ffmpeg.exe")

 if missing:
 raise EnvironmentError(f"Eksik bağımlılıklar: {', '.join(missing)}")

 def init_ui(self):
 layout = QGridLayout()

 # Logo
 self.init_logo(layout)

 # Tab Widget
 self.tabs = QTabWidget()
 layout.addWidget(self.tabs, 1, 0, 1, 4)

 # Video Tab
 self.init_video_tab()

 # Instagram Tab
 self.init_instagram_tab()

 # Progress Bar
 self.progress_bar = QProgressBar()
 layout.addWidget(self.progress_bar, 2, 0, 1, 4)

 # Log Output
 self.log_output = QTextEdit()
 self.log_output.setPlaceholderText("İndirme logları burada görünecek...")
 layout.addWidget(self.log_output, 3, 0, 1, 4)

 # Download Button
 self.download_button = QPushButton("🚀 İNDİRMEYİ BAŞLAT")
 self.download_button.setObjectName("download_button")
 self.download_button.clicked.connect(self.start_download)
 layout.addWidget(self.download_button, 4, 0, 1, 4)

 self.setLayout(layout)

 def init_logo(self, layout):
 self.logo_label = QLabel(self)
 if os.path.exists(self.logo_path):
 try:
 logo_pixmap = QPixmap(self.logo_path)
 self.logo_label.setPixmap(logo_pixmap.scaled(80, 80, Qt.AspectRatioMode.KeepAspectRatio))
 except Exception as e:
 print(f"Logo yüklenemedi: {str(e)}")
 self.logo_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop)
 layout.addWidget(self.logo_label, 0, 3, 1, 1, Qt.AlignmentFlag.AlignRight)

 def init_video_tab(self):
 video_tab = QWidget()
 video_layout = QGridLayout()

 # URL Input
 self.url_label = QLabel("📌 Video URL(ler):")
 video_layout.addWidget(self.url_label, 0, 0)

 self.url_input = QTextEdit()
 self.url_input.setPlaceholderText("Her satıra bir URL girin\nVeya TXT dosyası seçin")
 self.url_input.setMaximumHeight(80)
 video_layout.addWidget(self.url_input, 0, 1, 1, 3)

 # URL Buttons
 url_button_layout = QHBoxLayout()

 self.add_url_button = QPushButton("URL Ekle")
 self.add_url_button.setObjectName("add_url_button")
 self.add_url_button.clicked.connect(self.add_url)
 url_button_layout.addWidget(self.add_url_button)

 self.load_txt_button = QPushButton("TXT Yükle")
 self.load_txt_button.setObjectName("load_txt_button")
 self.load_txt_button.clicked.connect(self.load_urls_from_txt)
 url_button_layout.addWidget(self.load_txt_button)

 self.clear_urls_button = QPushButton("Temizle")
 self.clear_urls_button.setObjectName("clear_urls_button")
 self.clear_urls_button.clicked.connect(self.clear_urls)
 url_button_layout.addWidget(self.clear_urls_button)

 video_layout.addLayout(url_button_layout, 1, 1, 1, 3)

 # Save Path
 self.path_label = QLabel("📂 Kayıt Klasörü:")
 video_layout.addWidget(self.path_label, 2, 0)

 self.path_input = QLineEdit(self.downloads_path)
 video_layout.addWidget(self.path_input, 2, 1, 1, 2)

 self.browse_button = QPushButton("Gözat")
 self.browse_button.setObjectName("browse_button")
 self.browse_button.clicked.connect(lambda: self.browse_folder(self.path_input))
 video_layout.addWidget(self.browse_button, 2, 3)

 # Format Selection
 self.format_label = QLabel("🎬 Format:")
 video_layout.addWidget(self.format_label, 3, 0)

 self.format_combo = QComboBox()
 self.format_combo.addItems(["MP4 (Video+Ses)", "MP3 (Sadece Ses)", "M4A (Yüksek Kalite Ses)"])
 video_layout.addWidget(self.format_combo, 3, 1, 1, 3)

 # Quality Selection
 self.quality_label = QLabel("📶 Kalite:")
 video_layout.addWidget(self.quality_label, 4, 0)

 self.quality_combo = QComboBox()
 self.quality_combo.addItems(["Otomatik (En İyi)", "Manuel Seçim"])
 video_layout.addWidget(self.quality_combo, 4, 1, 1, 3)

 # Manual Quality
 self.manual_quality_input = QLineEdit()
 self.manual_quality_input.setPlaceholderText("Örn: 720, 1080, 4K")
 self.manual_quality_input.setEnabled(False)
 video_layout.addWidget(self.manual_quality_input, 5, 1, 1, 3)
 self.quality_combo.currentIndexChanged.connect(self.toggle_manual_quality)

 # Alternative Download Option
 self.alternative_download_layout = QHBoxLayout()
 self.alternative_download_checkbox = QCheckBox("Alternatif İndirme (Hızlı)")
 self.alternative_download_checkbox.setToolTip("Sadece en iyi formatı indirir, diğer ayarları dikkate almaz")
 self.alternative_download_layout.addWidget(self.alternative_download_checkbox)
 video_layout.addLayout(self.alternative_download_layout, 6, 0, 1, 4)

 # Advanced Settings
 self.advanced_group = QGroupBox("⚙️ Gelişmiş Ayarlar")
 advanced_layout = QGridLayout()

 # Thumbnail Options
 self.embed_thumbnail_checkbox = QCheckBox("Küçük resim ekle")
 advanced_layout.addWidget(self.embed_thumbnail_checkbox, 0, 0)

 self.write_thumbnail_checkbox = QCheckBox("Küçük resmi kaydet")
 advanced_layout.addWidget(self.write_thumbnail_checkbox, 0, 1)

 # Other Options
 self.subtitles_checkbox = QCheckBox("Altyazıları indir")
 advanced_layout.addWidget(self.subtitles_checkbox, 1, 0)

 self.metadata_checkbox = QCheckBox("Bilgileri ekle")
 advanced_layout.addWidget(self.metadata_checkbox, 1, 1)

 # Unique Names Solution
 self.unique_names_checkbox = QCheckBox("Benzersiz isimler")
 self.unique_names_checkbox.setChecked(True)
 self.unique_names_checkbox.setToolTip("Aynı isimli dosyaların üzerine yazılmasını engeller")
 advanced_layout.addWidget(self.unique_names_checkbox, 2, 0, 1, 2)

 self.advanced_group.setLayout(advanced_layout)
 video_layout.addWidget(self.advanced_group, 7, 0, 1, 4)

 video_tab.setLayout(video_layout)
 self.tabs.addTab(video_tab, "🎥 Video İndir")

 def init_instagram_tab(self):
 insta_tab = QWidget()
 insta_layout = QGridLayout()

 # URL Input
 self.insta_url_label = QLabel("📌 Instagram URL:")
 insta_layout.addWidget(self.insta_url_label, 0, 0)

 self.insta_url_input = QLineEdit()
 self.insta_url_input.setPlaceholderText("Örn: https://www.instagram.com/p/...")
 insta_layout.addWidget(self.insta_url_input, 0, 1, 1, 3)

 # Save Path
 self.insta_path_label = QLabel("📂 Kayıt Klasörü:")
 insta_layout.addWidget(self.insta_path_label, 1, 0)

 self.insta_path_input = QLineEdit(self.downloads_path)
 insta_layout.addWidget(self.insta_path_input, 1, 1, 1, 2)

 self.insta_browse_button = QPushButton("Gözat")
 self.insta_browse_button.setObjectName("insta_browse_button")
 self.insta_browse_button.clicked.connect(lambda: self.browse_folder(self.insta_path_input))
 insta_layout.addWidget(self.insta_browse_button, 1, 3)

 # Options
 self.insta_options_group = QGroupBox("📷 İndirme Seçenekleri")
 options_layout = QGridLayout()

 self.insta_high_quality_check = QCheckBox("Yüksek kalite")
 self.insta_high_quality_check.setChecked(True)
 options_layout.addWidget(self.insta_high_quality_check, 0, 0)

 self.insta_captions_check = QCheckBox("Açıklamaları kaydet")
 options_layout.addWidget(self.insta_captions_check, 0, 1)

 self.insta_stories_check = QCheckBox("Hikayeleri indir")
 options_layout.addWidget(self.insta_stories_check, 1, 0)

 self.insta_igtv_check = QCheckBox("IGTV indir")
 options_layout.addWidget(self.insta_igtv_check, 1, 1)

 self.insta_options_group.setLayout(options_layout)
 insta_layout.addWidget(self.insta_options_group, 2, 0, 1, 4)

 # Alternative Download Option
 self.insta_alternative_layout = QHBoxLayout()
 self.insta_alternative_checkbox = QCheckBox("Alternatif İndirme (gallery-dl)")
 self.insta_alternative_checkbox.setToolTip("Instagram içeriğini gallery-dl ile indirir")
 self.insta_alternative_layout.addWidget(self.insta_alternative_checkbox)
 insta_layout.addLayout(self.insta_alternative_layout, 3, 0, 1, 4)

 insta_tab.setLayout(insta_layout)
 self.tabs.addTab(insta_tab, "📷 Instagram İndir")

 def load_config(self):
 if os.path.exists(self.config_path):
 try:
 with open(self.config_path, 'r') as f:
 config = json.load(f)
 # Video ayarları
 self.path_input.setText(config.get('video_save_path', self.downloads_path))
 self.format_combo.setCurrentIndex(config.get('format_index', 0))
 self.quality_combo.setCurrentIndex(config.get('quality_index', 0))
 self.manual_quality_input.setText(config.get('manual_quality', ''))
 self.embed_thumbnail_checkbox.setChecked(config.get('embed_thumb', False))
 self.write_thumbnail_checkbox.setChecked(config.get('write_thumb', False))
 self.subtitles_checkbox.setChecked(config.get('subtitles', False))
 self.metadata_checkbox.setChecked(config.get('metadata', False))
 self.unique_names_checkbox.setChecked(config.get('unique_names', True))
 self.alternative_download_checkbox.setChecked(config.get('alternative_download', False))

 # Instagram ayarları
 self.insta_path_input.setText(config.get('insta_save_path', self.downloads_path))
 self.insta_high_quality_check.setChecked(config.get('insta_high_quality', True))
 self.insta_captions_check.setChecked(config.get('insta_captions', False))
 self.insta_stories_check.setChecked(config.get('insta_stories', False))
 self.insta_igtv_check.setChecked(config.get('insta_igtv', False))
 self.insta_alternative_checkbox.setChecked(config.get('insta_alternative', False))
 except Exception as e:
 print(f"Config yüklenirken hata: {str(e)}")

 def save_config(self):
 config = {
 # Video ayarları
 'video_save_path': self.path_input.text(),
 'format_index': self.format_combo.currentIndex(),
 'quality_index': self.quality_combo.currentIndex(),
 'manual_quality': self.manual_quality_input.text(),
 'embed_thumb': self.embed_thumbnail_checkbox.isChecked(),
 'write_thumb': self.write_thumbnail_checkbox.isChecked(),
 'subtitles': self.subtitles_checkbox.isChecked(),
 'metadata': self.metadata_checkbox.isChecked(),
 'unique_names': self.unique_names_checkbox.isChecked(),
 'alternative_download': self.alternative_download_checkbox.isChecked(),

 # Instagram ayarları
 'insta_save_path': self.insta_path_input.text(),
 'insta_high_quality': self.insta_high_quality_check.isChecked(),
 'insta_captions': self.insta_captions_check.isChecked(),
 'insta_stories': self.insta_stories_check.isChecked(),
 'insta_igtv': self.insta_igtv_check.isChecked(),
 'insta_alternative': self.insta_alternative_checkbox.isChecked()
 }
 with open(self.config_path, 'w') as f:
 json.dump(config, f)

 def add_url(self):
 url, ok = QInputDialog.getText(self, "URL Ekle", "İndirilecek URL'yi girin:")
 if ok and url:
 self.url_input.append(url.strip())

 def load_urls_from_txt(self):
 file_path, _ = QFileDialog.getOpenFileName(self, "TXT Dosyası Seç", "", "Text Files (*.txt);;All Files (*)")
 if file_path:
 try:
 with open(file_path, 'r', encoding='utf-8') as f:
 urls = [line.strip() for line in f if line.strip()]
 self.url_input.setPlainText('\n'.join(urls))
 self.append_log(f"✅ {len(urls)} URL TXT dosyasından yüklendi", "success")
 except Exception as e:
 QMessageBox.warning(self, "Hata", f"Dosya okunurken hata oluştu:\n{str(e)}")

 def clear_urls(self):
 self.url_input.clear()

 def browse_folder(self, target_input):
 folder = QFileDialog.getExistingDirectory(self, "Klasör Seç", self.downloads_path)
 if folder:
 target_input.setText(folder)

 def toggle_manual_quality(self):
 self.manual_quality_input.setEnabled(self.quality_combo.currentText() == "Manuel Seçim")

 def start_download(self):
 current_tab = self.tabs.currentIndex()

 if current_tab == 0: # Video sekmesi
 urls = [url.strip() for url in self.url_input.toPlainText().split('\n') if url.strip()]
 if not urls:
 QMessageBox.warning(self, "Uyarı", "Lütfen en az bir URL girin!")
 return

 self.save_config()
 self.download_videos(urls)

 elif current_tab == 1: # Instagram sekmesi
 url = self.insta_url_input.text().strip()
 if not url:
 QMessageBox.warning(self, "Uyarı", "Lütfen bir URL veya kullanıcı adı girin!")
 return

 self.save_config()
 if self.insta_alternative_checkbox.isChecked():
 self.download_instagram_with_gallery_dl(url)
 else:
 self.download_instagram(url)

 def download_videos(self, urls):
 self.progress_bar.setValue(0)
 self.log_output.clear()

 save_path = self.path_input.text().strip()
 if not save_path:
 QMessageBox.warning(self, "Uyarı", "Lütfen bir kayıt klasörü seçin!")
 return

 # Çıktı şablonunu ayarla (benzersiz isimler için)
 output_template = f"{save_path}/%(title)s.%(ext)s"
 if self.unique_names_checkbox.isChecked():
 output_template = f"{save_path}/%(title)s-%(id)s.%(ext)s"

 base_command = [
 self.yt_dlp_path,
 "-o", output_template,
 "--ffmpeg-location", self.ffmpeg_dir,
 "--no-warnings",
 "--newline",
 "--no-colors",
 "--no-playlist"
 ]

 # Alternatif indirme seçeneği
 if self.alternative_download_checkbox.isChecked():
 base_command.extend(["-f", "best"])
 else:
 # Format Seçimi
 format_choice = self.format_combo.currentText()
 if format_choice == "MP4 (Video+Ses)":
 if self.quality_combo.currentText() == "Manuel Seçim" and self.manual_quality_input.text().strip().isdigit():
 base_command.extend(["-f", f"bestvideo[height<={self.manual_quality_input.text().strip()}]+bestaudio"])
 else:
 base_command.extend(["-f", "bestvideo+bestaudio"])
 base_command.extend(["--merge-output-format", "mp4"])
 elif format_choice == "MP3 (Sadece Ses)":
 base_command.extend(["-x", "--audio-format", "mp3", "--audio-quality", "0"])
 elif format_choice == "M4A (Yüksek Kalite Ses)":
 base_command.extend(["-f", "bestaudio[ext=m4a]", "--audio-quality", "0"])

 # Diğer Ayarlar
 if self.embed_thumbnail_checkbox.isChecked():
 base_command.append("--embed-thumbnail")
 if self.write_thumbnail_checkbox.isChecked():
 base_command.extend(["--write-thumbnail", "--convert-thumbnails", "jpg"])
 if self.subtitles_checkbox.isChecked():
 base_command.extend(["--write-subs", "--sub-langs", "all", "--convert-subs", "srt"])
 if self.metadata_checkbox.isChecked():
 base_command.append("--embed-metadata")

 # URL'leri işle
 self.total_urls = len(urls)
 self.current_url_index = 0
 self.urls = urls
 self.base_command = base_command
 self.process_next_video()

 def download_instagram(self, url):
 self.progress_bar.setValue(0)
 self.log_output.clear()

 save_path = self.insta_path_input.text().strip()
 if not save_path:
 QMessageBox.warning(self, "Uyarı", "Lütfen bir kayıt klasörü seçin!")
 return

 try:
 import instaloader
 self.append_log("🔍 Instagram içeriği indiriliyor...", "info")

 L = instaloader.Instaloader(
 dirname_pattern=os.path.join(save_path, "{profile}", "{target}"),
 save_metadata=self.insta_captions_check.isChecked(),
 download_video_thumbnails=False,
 download_geotags=False,
 download_comments=False,
 compress_json=False
 )

 # İndirme seçenekleri
 options = {
 "profile": None,
 "fast_update": True,
 "download_videos": True,
 "download_pictures": True,
 "download_video_thumbnails": False,
 "download_geotags": False,
 "download_comments": False,
 "post_filter": None
 }

 if "/p/" in url: # Tek gönderi
 post = instaloader.Post.from_shortcode(L.context, url.split("/p/")[1].split("/")[0])
 L.download_post(post, target=post.owner_username)
 self.append_log(f"✅ Gönderi indirildi: {post.shortcode}", "success")
 elif "/stories/" in url: # Hikaye
 self.append_log("⚠️ Hikaye indirmek için giriş yapmalısınız", "warning")
 return
 else: # Profil
 profile = instaloader.Profile.from_username(L.context, url.split("/")[-1])

 if self.insta_stories_check.isChecked():
 self.append_log("⚠️ Hikaye indirmek için giriş yapmalısınız", "warning")

 if self.insta_igtv_check.isChecked():
 L.download_igtv(profile)
 self.append_log(f"✅ IGTV indirildi: {profile.username}", "success")

 L.download_profile(profile, profile_pic_only=False)
 self.append_log(f"✅ Profil indirildi: {profile.username}", "success")

 self.progress_bar.setValue(100)
 self.append_log("🎉 Instagram indirme tamamlandı!", "success")

 except Exception as e:
 self.append_log(f"❌ Hata: {str(e)}", "error")
 QMessageBox.warning(self, "Hata", f"Instagram indirme hatası:\n{str(e)}")

 def download_instagram_with_gallery_dl(self, url):
 self.progress_bar.setValue(0)
 self.log_output.clear()

 save_path = self.insta_path_input.text().strip()
 if not save_path:
 QMessageBox.warning(self, "Uyarı", "Lütfen bir kayıt klasörü seçin!")
 return

 command = [
 self.gallery_dl_path,
 "--directory", save_path,
 "--no-check-certificate",
 "--filename", "%(title)s.%(ext)s"
 ]

 if self.insta_captions_check.isChecked():
 command.append("--write-metadata")

 command.append(url)

 self.append_log("🔍 Instagram içeriği indiriliyor (gallery-dl)...", "info")
 self.run_command(command)

 def process_next_video(self):
 if self.current_url_index >= self.total_urls:
 self.append_log("\n🎉 TÜM İNDİRMELER BAŞARIYLA TAMAMLANDI!", "success")
 QMessageBox.information(self, "Başarılı", "Tüm indirmeler tamamlandı!")
 self.progress_bar.setValue(100)
 return

 url = self.urls[self.current_url_index]
 self.current_url_index += 1

 self.append_log(f"\n🔍 İndiriliyor: {url} ({self.current_url_index}/{self.total_urls})", "info")

 command = self.base_command.copy()
 command.append(url)

 self.process = QProcess(self)
 self.process.readyReadStandardOutput.connect(self.handle_stdout)
 self.process.readyReadStandardError.connect(self.handle_stderr)
 self.process.finished.connect(self.handle_finished)
 self.process.start(command[0], command[1:])

 def run_command(self, command):
 """Komutu çalıştırır ve çıktıyı yönetir"""
 self.process = QProcess(self)
 self.process.readyReadStandardOutput.connect(self.handle_stdout)
 self.process.readyReadStandardError.connect(self.handle_stderr)
 self.process.finished.connect(self.handle_finished)
 self.process.start(command[0], command[1:])

 def handle_stdout(self):
 data = self.process.readAllStandardOutput()
 stdout = bytes(data).decode("utf8", errors='ignore').strip()
 if stdout:
 self.append_log(stdout, "info")
 if "%" in stdout:
 try:
 progress = float(re.search(r'(\d+\.\d+)%', stdout).group(1))
 self.progress_bar.setValue(int(progress))
 except:
 pass

 def handle_stderr(self):
 data = self.process.readAllStandardError()
 stderr = bytes(data).decode("utf8", errors='ignore').strip()
 if stderr:
 self.append_log(stderr, "error")

 def handle_finished(self, exit_code, exit_status):
 if exit_code == 0:
 self.append_log("✅ İndirme tamamlandı", "success")
 if hasattr(self, 'process_next_video'):
 self.process_next_video()
 else:
 self.progress_bar.setValue(100)
 QMessageBox.information(self, "Başarılı", "İndirme tamamlandı!")
 else:
 self.append_log(f"❌ Hata! Çıkış Kodu: {exit_code}", "error")
 if hasattr(self, 'process_next_video'):
 self.process_next_video()
 else:
 QMessageBox.warning(self, "Hata", "İndirme sırasında bir hata oluştu!")

 def append_log(self, message, msg_type="info"):
 cursor = self.log_output.textCursor()
 cursor.movePosition(QTextCursor.MoveOperation.End)

 if msg_type == "error":
 color = "#ff4444" # Kırmızı
 elif msg_type == "success":
 color = "#44ff44" # Yeşil
 elif msg_type == "warning":
 color = "#ffff44" # Sarı
 else:
 color = "#ffffff" # Beyaz

 self.log_output.setTextColor(QColor(color))
 cursor.insertText(message + "\n")
 self.log_output.setTextColor(QColor("#e0e0e0"))

 self.log_output.ensureCursorVisible()

 def closeEvent(self, event):
 self.save_config()
 event.accept()

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

Kodum bu: (ek: Pek okumamışım pek yardımcı olmaz ama silemediğim için duracak yapacak bir şey yok.)
 
Son düzenleyen: Moderatör:
@Daiquiri Manuel olarak paketleyip doğrudan import ettin mi?
 
@Daiquiri Manuel olarak paketleyip doğrudan import ettin mi?

"--Hidden-import = yt_dlp" hocam eğer bunu diyorsanız evet yaptım.

YT-DLP'yi EXE olarak dizindeki datas klasörüne koydum

Bunu denemedim belki işe yarayabilir. Sorun şu ki, düne kadar hiçbir sorun yoktu. PyCharm da paketler kısmında bile dokümantasyon sayfası gelmiyor YT-DLP'nin. IDE bozuldu herhalde bilemiyorum.
 
Python:
pyinstaller --onefile --hidden-import=yt_dlp --collect-submodules=yt_dlp --collect-data=yt_dlp scriptin.py

Python:
import yt_dlp

Bu bu sıra ile tekrar deneyebilir misin acaba?

Büyük ihtimalle sen alttakini yazdın. Benim yazdığım daha garanti.
Python:
pyinstaller --onefile --hidden-import=yt_dlp your_script.py

Yanlış anlama bende yeni başlamış sayılırım. Aklıma bu geldi. Eğer yine işe yaramazsa .spec dosyasını düzenle. Bende fikir tükendi.
 
Son düzenleme:
Python:
pyinstaller --onefile --hidden-import=yt_dlp --collect-submodules=yt_dlp --collect-data=yt_dlp scriptin.py

Python:
import yt_dlp

Bu bu sıra ile tekrar deneyebilir misin acaba?

Büyük ihtimalle sen alttakini yazdın. Benim yazdığım daha garanti.
Python:
pyinstaller --onefile --hidden-import=yt_dlp your_script.py

Yanlış anlama bende yeni başlamış sayılırım. Aklıma bu geldi. Eğer yine işe yaramazsa .spec dosyasını düzenle. Bende fikir tükendi.
İşe yaramadı spec'i de denedim.

YT-DLP kullanarak bir program yazdım. Düne kadar bir sorun yoktu ama dün EXE dosyasına çevirince YT-DLP kütüphanesi EXE'ye dahil edilmedi. PyCharm'da paketler kısmına baktım YT-DLP dokümantasyon sayfası da açılmıyor. Diğer paketlerin dokümantasyon sayfası geliyor ve onlar EXE'ye çevirirken projeye de dahil ediliyor, onlarda bir sorun yok. YT-DLP'yi kaldırdım, yükledim, olmadı. Eski sürümü kurdum, yine olmadı. Örnek olması açısından pip ve YT-DLP'nin bölümlerinin fotoğrafını bırakıyorum. Gördüğünüz gibi YT-DLP'yi seçince herhangi bir şey gözükmüyor. Çözüm önerisi olan var mı? (PyCharm 2025.1)

Eki Görüntüle 2474624

Eki Görüntüle 2474625

Sorun çözüldü. Yeni bir Python interpreter oluşturdum. YT-DLP dokümantasyon sayfası yine gözükmüyor ama EXE'ye otomatik olarak dahil ediyor. EXE'ye çevirince sorunsuz çalışıyor.
 
Son düzenleyen: Moderatör:
Çözüm

Technopat Haberler

Yeni konular

Geri
Yukarı