SHARE
    TWEET
    Najeebsk

    IPTV-PLAYER-ALL4.0.pyw

    Jul 17th, 2024
    566
    0
    Never
    Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
    Python 12.90 KB | None | 0 0
    1. import os
    2. import tkinter as tk
    3. from tkinter import ttk, messagebox, filedialog
    4. import vlc
    5. import subprocess
    6. import threading
    7. import time
    8. # Path to VLC executable
    9. VLC_PATH = r"C:\Program Files\VideoLAN\VLC\vlc.exe"
    10. class ChannelPlayer:
    11. def __init__(self, root):
    12. self.root = root
    13. self.root.title("Najeeb Live Videos and IPTV Channels Player")
    14. self.channels = {}
    15. self.current_instance = None
    16. self.player = None
    17. self.media = None
    18. self.is_dragging_slider = False
    19. self.is_fullscreen = False
    20. self.is_muted = False
    21. self.process = None
    22. self.recording_process = None # To store the subprocess for recording
    23. self.create_widgets()
    24. self.auto_load_channels()
    25. def auto_load_channels(self):
    26. script_dir = os.path.dirname(os.path.abspath(__file__))
    27. channels_dir = os.path.join(script_dir, "CHANNELS")
    28. if not os.path.exists(channels_dir):
    29. os.makedirs(channels_dir)
    30. playlist_files = [file for file in os.listdir(channels_dir) if file.endswith(('.m3u', '.m3u8', '.txt'))]
    31. for file_name in playlist_files:
    32. file_path = os.path.join(channels_dir, file_name)
    33. self.load_channels(file_path)
    34. def load_channels(self, file_path):
    35. try:
    36. with open(file_path, 'r', encoding='utf-8') as file:
    37. for line in file:
    38. parts = line.strip().split(maxsplit=1)
    39. if len(parts) == 2:
    40. self.channels[parts[0]] = parts[1]
    41. self.update_channel_dropdown()
    42. except FileNotFoundError:
    43. messagebox.showerror("Error", f"File not found: {file_path}")
    44. except UnicodeDecodeError:
    45. messagebox.showerror("Error", "Error decoding the file. Please ensure it is in UTF-8 format.")
    46. except Exception as e:
    47. messagebox.showerror("Error", str(e))
    48. def update_channel_dropdown(self):
    49. self.channel_dropdown['values'] = list(self.channels.keys())
    50. def create_widgets(self):
    51. style = ttk.Style()
    52. style.configure('TButton', font=('Helvetica', 10))
    53. style.configure('TCombobox', font=('Helvetica', 10))
    54. # Search field for channel title
    55. self.search_label = ttk.Label(self.root, text="Search Channel Title:")
    56. self.search_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")
    57. self.search_var = tk.StringVar()
    58. self.search_entry = ttk.Entry(self.root, textvariable=self.search_var)
    59. self.search_entry.grid(row=0, column=1, columnspan=2, padx=5, pady=5, sticky="ew")
    60. self.search_entry.bind("<KeyRelease>", self.filter_channels)
    61. # Browse button for URLs file
    62. self.browse_button = ttk.Button(self.root, text="Browse", command=self.browse_file)
    63. self.browse_button.grid(row=0, column=3, padx=5, pady=5, sticky="ew")
    64. # Channel selection
    65. self.channel_var = tk.StringVar()
    66. self.channel_dropdown = ttk.Combobox(self.root, textvariable=self.channel_var)
    67. self.channel_dropdown.grid(row=1, column=0, columnspan=2, padx=5, pady=5, sticky="ew")
    68. # Preview button
    69. self.preview_button = ttk.Button(self.root, text="Preview", command=self.preview_channel)
    70. self.preview_button.grid(row=1, column=2, padx=5, pady=5, sticky="ew")
    71. # Stop preview button
    72. self.stop_preview_button = ttk.Button(self.root, text="Stop Preview", command=self.stop_preview)
    73. self.stop_preview_button.grid(row=1, column=3, padx=5, pady=5, sticky="ew")
    74. # Play button
    75. self.play_button = ttk.Button(self.root, text="Play", command=self.play_channel)
    76. self.play_button.grid(row=1, column=4, padx=5, pady=5, sticky="ew")
    77. # Volume control
    78. self.volume_slider = ttk.Scale(self.root, from_=0, to=200, orient=tk.HORIZONTAL, command=self.set_volume)
    79. self.volume_slider.set(50) # Set initial volume to 50%
    80. self.volume_slider.grid(row=1, column=5, padx=5, pady=5, sticky="ew")
    81. # Mute button
    82. self.mute_button = ttk.Button(self.root, text="Mute", command=self.toggle_mute)
    83. self.mute_button.grid(row=1, column=6, padx=5, pady=5, sticky="ew")
    84. # Full screen button
    85. self.fullscreen_button = ttk.Button(self.root, text="Full Screen", command=self.toggle_fullscreen)
    86. self.fullscreen_button.grid(row=1, column=7, padx=5, pady=5, sticky="ew")
    87. # VLC video frame
    88. self.video_frame = tk.Frame(self.root, bg="black", height=300)
    89. self.video_frame.grid(row=2, column=0, columnspan=8, padx=5, pady=5, sticky="nsew")
    90. # Video control slider
    91. self.video_slider = ttk.Scale(self.root, from_=0, to=1000, orient=tk.HORIZONTAL)
    92. self.video_slider.grid(row=3, column=0, columnspan=8, padx=5, pady=5, sticky="ew")
    93. self.video_slider.bind("<ButtonPress-1>", self.slider_pressed)
    94. self.video_slider.bind("<ButtonRelease-1>", self.slider_released)
    95. # Capture video button
    96. self.capture_video_button = ttk.Button(self.root, text="Capture Video", command=self.capture_video)
    97. self.capture_video_button.grid(row=4, column=0, padx=5, pady=5, sticky="ew")
    98. # Record audio button
    99. self.record_audio_button = ttk.Button(self.root, text="Record Audio", command=self.record_audio)
    100. self.record_audio_button.grid(row=4, column=1, padx=5, pady=5, sticky="ew")
    101. # Stop recording button
    102. self.stop_record_button = ttk.Button(self.root, text="Stop Recording", command=self.stop_recording)
    103. self.stop_record_button.grid(row=4, column=2, padx=5, pady=5, sticky="ew")
    104. # Capture screenshots button
    105. self.capture_screenshots_button = ttk.Button(self.root, text="Capture Screenshots", command=self.capture_screenshots)
    106. self.capture_screenshots_button.grid(row=4, column=3, padx=5, pady=5, sticky="ew")
    107. # Copy to clipboard button
    108. self.copy_button = ttk.Button(self.root, text="Copy URL", command=self.copy_to_clipboard)
    109. self.copy_button.grid(row=4, column=4, padx=5, pady=5, sticky="ew")
    110. self.root.grid_rowconfigure(2, weight=1)
    111. self.root.grid_rowconfigure(3, weight=0)
    112. self.root.grid_rowconfigure(4, weight=0)
    113. self.root.grid_columnconfigure(0, weight=1)
    114. self.root.grid_columnconfigure(1, weight=1)
    115. self.root.grid_columnconfigure(2, weight=1)
    116. self.root.grid_columnconfigure(3, weight=1)
    117. self.root.grid_columnconfigure(4, weight=1)
    118. self.root.grid_columnconfigure(5, weight=1)
    119. self.root.grid_columnconfigure(6, weight=1)
    120. self.root.grid_columnconfigure(7, weight=1)
    121. self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
    122. def browse_file(self):
    123. file_path = filedialog.askopenfilename(
    124. title="Select URLs file",
    125. filetypes=(("M3U files", "*.m3u"), ("M3U8 files", "*.m3u8"), ("TEXT files", "*.txt"), ("All files", "*.*"))
    126. )
    127. if file_path:
    128. self.load_channels(file_path)
    129. def filter_channels(self, event):
    130. search_term = self.search_var.get().lower()
    131. filtered_channels = [channel for channel in self.channels.keys() if search_term in channel.lower()]
    132. self.channel_dropdown['values'] = filtered_channels
    133. def preview_channel(self):
    134. self.stop_preview()
    135. channel = self.channel_var.get()
    136. if channel and channel in self.channels:
    137. url = self.channels[channel]
    138. self.current_instance = vlc.Instance()
    139. self.player = self.current_instance.media_player_new()
    140. self.player.set_hwnd(self.video_frame.winfo_id())
    141. self.media = self.current_instance.media_new(url)
    142. self.player.set_media(self.media)
    143. self.player.play()
    144. self.update_video_slider()
    145. def stop_preview(self):
    146. if self.player:
    147. self.player.stop()
    148. self.player.release()
    149. self.player = None
    150. if self.current_instance:
    151. self.current_instance.release()
    152. self.current_instance = None
    153. def play_channel(self):
    154. self.stop_preview()
    155. channel = self.channel_var.get()
    156. if channel and channel in self.channels:
    157. url = self.channels[channel]
    158. subprocess.Popen([VLC_PATH, url])
    159. def set_volume(self, value):
    160. if self.player:
    161. volume = int(float(value))
    162. if volume > 200:
    163. volume = 200
    164. self.player.audio_set_volume(volume)
    165. def toggle_mute(self):
    166. if self.player:
    167. self.is_muted = not self.is_muted
    168. self.player.audio_toggle_mute()
    169. self.mute_button.config(text="Unmute" if self.is_muted else "Mute")
    170. def slider_pressed(self, event):
    171. self.is_dragging_slider = True
    172. def slider_released(self, event):
    173. self.is_dragging_slider = False
    174. self.set_position(self.video_slider.get())
    175. def set_position(self, value):
    176. if self.player:
    177. self.player.set_position(float(value) / 1000.0)
    178. def update_video_slider(self):
    179. if self.player and not self.is_dragging_slider:
    180. position = self.player.get_position() * 1000
    181. self.video_slider.set(position)
    182. self.root.after(1000, self.update_video_slider)
    183. def toggle_fullscreen(self):
    184. self.is_fullscreen = not self.is_fullscreen
    185. self.root.attributes("-fullscreen", self.is_fullscreen)
    186. self.fullscreen_button.config(text="Exit Full Screen" if self.is_fullscreen else "Full Screen")
    187. def on_closing(self):
    188. self.stop_preview()
    189. if self.process:
    190. self.process.terminate()
    191. if self.recording_process:
    192. self.recording_process.terminate()
    193. self.root.destroy()
    194. def capture_video(self):
    195. try:
    196. selected_channel = self.channel_var.get().strip()
    197. if selected_channel in self.channels:
    198. url = self.channels[selected_channel]
    199. filename = filedialog.asksaveasfilename(defaultextension=".mp4", filetypes=[("MP4 files", "*.mp4")])
    200. if filename:
    201. command = ['ffmpeg', '-y', '-i', url, '-t', '03:55:00', '-c', 'copy', filename]
    202. threading.Thread(target=lambda: subprocess.run(command)).start()
    203. messagebox.showinfo("Capturing", f"Capturing 03:55 minutes of video to {filename}")
    204. else:
    205. messagebox.showerror("Error", "Selected text is not a valid URL.")
    206. except tk.TclError:
    207. messagebox.showerror("Error", "No text selected.")
    208. def record_audio(self):
    209. try:
    210. selected_channel = self.channel_var.get().strip()
    211. if selected_channel in self.channels:
    212. url = self.channels[selected_channel]
    213. filename = filedialog.asksaveasfilename(defaultextension=".mp3", filetypes=[("MP3 files", "*.mp3")])
    214. if filename:
    215. command = ['ffmpeg', '-y', '-i', url, '-f', 'mp3', '-c:a', 'libmp3lame', filename]
    216. self.process = subprocess.Popen(command)
    217. messagebox.showinfo("Recording", f"Recording audio to {filename}")
    218. else:
    219. messagebox.showerror("Error", "Selected text is not a valid URL.")
    220. except tk.TclError:
    221. messagebox.showerror("Error", "No text selected.")
    222. def stop_recording(self):
    223. if self.process:
    224. self.process.terminate()
    225. self.process = None
    226. messagebox.showinfo("Stopped", "Recording stopped")
    227. def capture_screenshots(self):
    228. if self.player.get_media():
    229. filename_base = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png")])
    230. if filename_base:
    231. interval = 5
    232. num_screenshots = 5
    233. for i in range(num_screenshots):
    234. time.sleep(interval)
    235. filename = f"{filename_base}_{i + 1}.png"
    236. self.player.video_take_snapshot(0, filename, 0, 0)
    237. messagebox.showinfo("Capturing Screenshots", f"Captured {num_screenshots} screenshots every {interval} seconds to {filename_base}")
    238. def copy_to_clipboard(self):
    239. channel = self.channel_var.get()
    240. if channel and channel in self.channels:
    241. url = self.channels[channel]
    242. self.root.clipboard_clear()
    243. self.root.clipboard_append(url)
    244. messagebox.showinfo("Copied", f"URL copied to clipboard: {url}")
    245. else:
    246. messagebox.showerror("Error", "No channel selected or invalid channel.")
    247. if __name__ == "__main__":
    248. root = tk.Tk()
    249. app = ChannelPlayer(root)
    250. root.mainloop()
    Advertisement
    Add Comment
    Please, Sign In to add comment
    Public Pastes
    We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
    Not a member of Pastebin yet?
    Sign Up, it unlocks many cool features!

    AltStyle によって変換されたページ (->オリジナル) /