# vlc_iptv_player.py import os import sys import time import ctypes import requests import subprocess from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QListWidget, QPushButton, QWidget, QHBoxLayout, QListWidgetItem, QLabel, QTextEdit from PyQt5.QtCore import Qt, QTimer, pyqtSignal import vlc class VLCPlayer: def __init__(self): vlc_args = [ "--avcodec-hw=any", "--network-caching=3000", "--no-video-title-show", "--vout=direct3d11" # or "win32" if needed ] if sys.platform == "win32": vlc_dir = os.path.join(os.path.dirname(__file__), "vlc") os.environ['PATH'] = vlc_dir + os.pathsep + os.environ['PATH'] try: ctypes.windll.kernel32.SetDllDirectoryW(vlc_dir) except: pass self.instance = vlc.Instance(vlc_args) self.media_player = self.instance.media_player_new() def play_stream(self, url): print(f"[VLC] Playing stream: {url}") if self.media_player.is_playing(): self.media_player.stop() time.sleep(0.5) media = self.instance.media_new(url) media.add_option(":network-caching=3000") media.add_option(":file-caching=3000") media.add_option(":live-caching=3000") self.media_player.set_media(media) result = self.media_player.play() time.sleep(1) # Force fullscreen off first to show window self.media_player.set_fullscreen(False) # Force window open workaround (toggle twice) self.media_player.toggle_fullscreen() self.media_player.toggle_fullscreen() state = self.media_player.get_state() print(f"[VLC] State: {state}, Has Video Output: {self.media_player.has_vout()}") if result == -1: print("[VLC] Failed to start playback.") else: print("[VLC] Playback started.") def stop(self): self.media_player.stop() def toggle_fullscreen(self): self.media_player.set_fullscreen(not self.media_player.get_fullscreen()) def release(self): self.media_player.release() self.instance.release() class PlaylistWindow(QMainWindow): channel_selected = pyqtSignal(str) # URL only def __init__(self, php_dir): super().__init__() self.setWindowTitle("Playlist") self.setGeometry(100, 100, 500, 600) self.php_dir = php_dir self.init_ui() self.download_playlist() def init_ui(self): widget = QWidget() layout = QVBoxLayout() self.channel_list = QListWidget() layout.addWidget(self.channel_list) controls = QHBoxLayout() self.play_button = QPushButton("Play") self.play_button.clicked.connect(self.on_play_clicked) controls.addWidget(self.play_button) self.update_button = QPushButton("Update Playlist") self.update_button.clicked.connect(self.download_playlist) controls.addWidget(self.update_button) layout.addLayout(controls) widget.setLayout(layout) self.setCentralWidget(widget) def on_play_clicked(self): item = self.channel_list.currentItem() if item: url = item.data(Qt.UserRole) self.channel_selected.emit(url) def download_playlist(self): try: os.makedirs(self.php_dir, exist_ok=True) playlist_url = "https://iptv.nywebforum.com/playlist.m3u" response = requests.get(playlist_url, timeout=10) content = response.text # Extract EPG URL if needed if "x-tvg-url=" in content: epg_url = content.split('x-tvg-url="')[1].split('"')[0] print(f"EPG URL: {epg_url}") # Replace external URL with localhost content = content.replace( "https://iptv.nywebforum.com", f"http://localhost:8888" ) playlist_path = os.path.join(self.php_dir, "playlist.m3u") with open(playlist_path, "w", encoding="utf-8") as f: f.write(content) self.load_playlist(playlist_path) except Exception as e: print(f"Failed to download playlist: {e}") def load_playlist(self, playlist_path): try: with open(playlist_path, "r", encoding="utf-8") as f: lines = f.readlines() self.channel_list.clear() current_name = None for line in lines: line = line.strip() if line.startswith("#EXTINF:"): parts = line.split(',') current_name = parts[-1].strip() if len(parts) > 1 else "Unknown" elif line and not line.startswith("#") and current_name: item = QListWidgetItem(current_name) item.setData(Qt.UserRole, line) self.channel_list.addItem(item) current_name = None except Exception as e: print(f"Failed to load playlist: {e}") def start_php_server(php_dir, port=8888): try: os.chdir(php_dir) return subprocess.Popen( ["php", "-S", f"localhost:{port}"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0 ) except Exception as e: print(f"Failed to start PHP server: {e}") return None if __name__ == "__main__": php_dir = os.path.join(os.path.dirname(__file__), "php_files") os.makedirs(php_dir, exist_ok=True) # Start PHP server php_process = start_php_server(php_dir) # Launch Qt app (playlist only) app = QApplication(sys.argv) player = VLCPlayer() playlist_window = PlaylistWindow(php_dir) playlist_window.channel_selected.connect(player.play_stream) playlist_window.show() exit_code = app.exec_() # Cleanup VLC player.stop() player.release() # Stop PHP server if php_process: php_process.terminate() try: php_process.wait(timeout=2) except subprocess.TimeoutExpired: php_process.kill() sys.exit(exit_code)