SHARE
    TWEET
    Najeebsk

    IPTV.pyw

    Jul 19th, 2024 (edited)
    542
    0
    Never
    Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
    Python 11.16 KB | None | 0 0
    1. import os
    2. import tkinter as tk
    3. from tkinter import ttk, filedialog, messagebox
    4. import vlc
    5. import subprocess
    6. import threading
    7. # Constants
    8. CHANNELS_FOLDER = 'CHANNELS'
    9. VLC_PATH = r"C:\Program Files\VideoLAN\VLC\vlc.exe"
    10. WGET_PATH = r"C:\CMDER\APP\wget.exe" # Update this with the correct path to wget.exe
    11. FFMPEG_PATH = r"C:\CMDER\APP\ffmpeg.exe" # Update this with the correct path to ffmpeg.exe
    12. # Initialize VLC
    13. instance = vlc.Instance('--verbose 2')
    14. player = instance.media_player_new()
    15. class NajeebChannelPlayer(tk.Tk):
    16. def __init__(self):
    17. super().__init__()
    18. self.title("Najeeb IPTV Channel Player")
    19. self.geometry("1000x600")
    20. self.configure(bg='#2E2E2E')
    21. self.channels_info = {}
    22. self.process = None
    23. self.is_fullscreen = False
    24. self.is_dragging_slider = False # Initialize as an instance variable
    25. self.is_muted = False
    26. self.create_widgets()
    27. self.load_channels_from_folder()
    28. self.update_video_slider()
    29. def create_widgets(self):
    30. self.control_frame = ttk.Frame(self, style="TFrame")
    31. self.control_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=5)
    32. self.search_entry = ttk.Entry(self.control_frame, width=50)
    33. self.search_entry.pack(side=tk.LEFT, padx=5, pady=5)
    34. search_button = ttk.Button(self.control_frame, text="Search", command=self.search_channels)
    35. search_button.pack(side=tk.LEFT, padx=5, pady=5)
    36. filter_button = ttk.Button(self.control_frame, text="Filter", command=self.filter_channels)
    37. filter_button.pack(side=tk.LEFT, padx=5, pady=5)
    38. copy_button = ttk.Button(self.control_frame, text="Copy URL", command=self.copy_selected_url)
    39. copy_button.pack(side=tk.LEFT, padx=5, pady=5)
    40. preview_button = ttk.Button(self.control_frame, text="Preview", command=self.preview_selected_channel)
    41. preview_button.pack(side=tk.LEFT, padx=5, pady=5)
    42. stop_button = ttk.Button(self.control_frame, text="Stop Preview", command=self.stop_preview)
    43. stop_button.pack(side=tk.LEFT, padx=5, pady=5)
    44. # Volume and Mute Controls
    45. volume_frame = ttk.Frame(self.control_frame, style="TFrame")
    46. volume_frame.pack(side=tk.LEFT, padx=5, pady=5)
    47. volume_label = ttk.Label(volume_frame, text="Volume")
    48. volume_label.pack(side=tk.LEFT)
    49. volume_slider = ttk.Scale(volume_frame, from_=0, to=100, orient=tk.HORIZONTAL, command=self.set_volume)
    50. volume_slider.set(50) # Default volume
    51. volume_slider.pack(side=tk.LEFT, padx=5)
    52. self.mute_button = ttk.Button(volume_frame, text="Mute", command=self.mute_unmute)
    53. self.mute_button.pack(side=tk.LEFT, padx=5)
    54. # Additional Buttons
    55. self.additional_buttons_frame = ttk.Frame(self, style="TFrame")
    56. self.additional_buttons_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=5)
    57. capture_video_button = ttk.Button(self.additional_buttons_frame, text="Capture Video", command=self.capture_video)
    58. capture_video_button.pack(side=tk.LEFT, padx=5, pady=5)
    59. record_audio_button = ttk.Button(self.additional_buttons_frame, text="Record Audio", command=self.record_audio)
    60. record_audio_button.pack(side=tk.LEFT, padx=5, pady=5)
    61. stop_record_button = ttk.Button(self.additional_buttons_frame, text="Stop Recording", command=self.stop_recording)
    62. stop_record_button.pack(side=tk.LEFT, padx=5, pady=5)
    63. screenshot_button = ttk.Button(self.additional_buttons_frame, text="Capture Screenshots", command=self.capture_screenshots)
    64. screenshot_button.pack(side=tk.LEFT, padx=5, pady=5)
    65. fullscreen_button = ttk.Button(self.additional_buttons_frame, text="Full Screen", command=self.toggle_fullscreen)
    66. fullscreen_button.pack(side=tk.LEFT, padx=5, pady=5)
    67. download_button = ttk.Button(self.additional_buttons_frame, text="Download with wget", command=self.download_video)
    68. download_button.pack(side=tk.LEFT, padx=5, pady=5)
    69. download_ffmpeg_button = ttk.Button(self.additional_buttons_frame, text="Download with ffmpeg", command=self.download_with_ffmpeg)
    70. download_ffmpeg_button.pack(side=tk.LEFT, padx=5, pady=5)
    71. # Video control slider
    72. self.video_slider = ttk.Scale(self, from_=0, to=1000, orient=tk.HORIZONTAL)
    73. self.video_slider.pack(side=tk.BOTTOM, fill=tk.X, padx=5, pady=5)
    74. self.video_slider.bind("<ButtonPress-1>", self.slider_pressed)
    75. self.video_slider.bind("<ButtonRelease-1>", self.slider_released)
    76. self.result_frame = ttk.Frame(self, style="TFrame")
    77. self.result_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False, padx=1, pady=5)
    78. self.result_text = tk.Listbox(self.result_frame, width=30, height=25, selectmode=tk.SINGLE, bg='#FFFFFF', fg='#000000')
    79. self.result_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=False)
    80. # Add scrollbars
    81. vsb = ttk.Scrollbar(self.result_frame, orient="vertical", command=self.result_text.yview)
    82. vsb.pack(side=tk.RIGHT, fill="y")
    83. self.result_text.configure(yscrollcommand=vsb.set)
    84. self.result_text.bind('<Double-1>', self.play_selected_channel)
    85. self.video_frame = tk.Frame(self, bg='#000000')
    86. self.video_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10, pady=5)
    87. self.video_panel = tk.Frame(self.video_frame, bg='#000000')
    88. self.video_panel.pack(fill=tk.BOTH, expand=True)
    89. # Ensure control frames are always visible
    90. self.control_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=5)
    91. self.additional_buttons_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=5)
    92. def load_channels_from_folder(self):
    93. try:
    94. files = [f for f in os.listdir(CHANNELS_FOLDER) if f.endswith('.txt')]
    95. all_channels = []
    96. for file in files:
    97. file_path = os.path.join(CHANNELS_FOLDER, file)
    98. with open(file_path, 'r', encoding='utf-8') as f:
    99. all_channels.extend(f.readlines())
    100. self.process_text_data(all_channels)
    101. except FileNotFoundError:
    102. messagebox.showerror("Error", f"The folder '{CHANNELS_FOLDER}' does not exist.")
    103. except PermissionError:
    104. messagebox.showerror("Error", f"Permission denied while accessing '{CHANNELS_FOLDER}'.")
    105. except Exception as e:
    106. self.result_text.insert(tk.END, f"Error loading channels from folder: {str(e)}\n")
    107. def process_text_data(self, text_data):
    108. self.result_text.delete(0, tk.END)
    109. self.channels_info = {}
    110. for line in text_data:
    111. line = line.strip()
    112. if line:
    113. if "http" in line:
    114. # Find the URL by splitting on space
    115. parts = line.split(' ', 1)
    116. if len(parts) == 2:
    117. channel_name = parts[0].strip()
    118. url = parts[1].strip()
    119. self.channels_info[channel_name] = url
    120. self.result_text.insert(tk.END, channel_name)
    121. def search_channels(self):
    122. search_term = self.search_entry.get().lower()
    123. self.result_text.delete(0, tk.END)
    124. for channel_name, url in self.channels_info.items():
    125. if search_term in channel_name.lower():
    126. self.result_text.insert(tk.END, channel_name)
    127. def filter_channels(self):
    128. search_term = self.search_entry.get().lower()
    129. self.result_text.delete(0, tk.END)
    130. for channel_name, url in self.channels_info.items():
    131. if search_term in channel_name.lower() or search_term in url.lower():
    132. self.result_text.insert(tk.END, channel_name)
    133. def play_selected_channel(self, event):
    134. try:
    135. selected_channel = self.result_text.get(tk.ACTIVE)
    136. if selected_channel in self.channels_info:
    137. url = self.channels_info[selected_channel]
    138. subprocess.Popen([VLC_PATH, url])
    139. except (tk.TclError, KeyError):
    140. pass
    141. def preview_selected_channel(self):
    142. try:
    143. selected_channel = self.result_text.get(tk.ACTIVE)
    144. if selected_channel in self.channels_info:
    145. url = self.channels_info[selected_channel]
    146. self.play_vlc_stream(url)
    147. except (tk.TclError, KeyError):
    148. pass
    149. def play_vlc_stream(self, stream_url):
    150. media = instance.media_new(stream_url)
    151. player.set_media(media)
    152. player.set_hwnd(self.video_panel.winfo_id())
    153. player.play()
    154. def slider_pressed(self, event):
    155. self.is_dragging_slider = True
    156. def slider_released(self, event):
    157. self.is_dragging_slider = False
    158. value = self.video_slider.get()
    159. self.set_position(value)
    160. def set_position(self, value):
    161. player.set_time(int((value / 1000) * player.get_length()))
    162. def update_video_slider(self):
    163. if player and not self.is_dragging_slider:
    164. length = player.get_length()
    165. time = player.get_time()
    166. if length > 0:
    167. value = int((time / length) * 1000)
    168. self.video_slider.set(value)
    169. self.after(1000, self.update_video_slider)
    170. def set_volume(self, value):
    171. player.audio_set_volume(int(float(value))) # Convert float to int
    172. def mute_unmute(self):
    173. if self.is_muted:
    174. player.audio_set_mute(False)
    175. self.mute_button.config(text="Mute")
    176. else:
    177. player.audio_set_mute(True)
    178. self.mute_button.config(text="Unmute")
    179. self.is_muted = not self.is_muted
    180. def capture_video(self):
    181. self.process = subprocess.Popen(['ffmpeg', '-f', 'gdigrab', '-framerate', '30', '-i', 'desktop', 'output.mp4'])
    182. def record_audio(self):
    183. self.process = subprocess.Popen(['ffmpeg', '-f', 'dshow', '-i', 'audio=Stereo Mix (Realtek(R) Audio)', 'output_audio.mp3'])
    184. def stop_recording(self):
    185. if self.process:
    186. self.process.terminate()
    187. self.process = None
    188. def capture_screenshots(self):
    189. subprocess.Popen(['ffmpeg', '-f', 'gdigrab', '-framerate', '1', '-i', 'desktop', '-frames:v', '1', 'screenshot.png'])
    190. def copy_selected_url(self):
    191. selected_channel = self.result_text.get(tk.ACTIVE)
    192. if selected_channel in self.channels_info:
    193. url = self.channels_info[selected_channel]
    194. self.clipboard_clear()
    195. self.clipboard_append(url)
    196. def toggle_fullscreen(self):
    197. self.is_fullscreen = not self.is_fullscreen
    198. self.attributes("-fullscreen", self.is_fullscreen)
    199. def stop_preview(self):
    200. player.stop()
    201. def download_video(self):
    202. url = self.search_entry.get()
    203. if url:
    204. subprocess.Popen([WGET_PATH, url])
    205. def download_with_ffmpeg(self):
    206. url = self.search_entry.get()
    207. if url:
    208. subprocess.Popen([FFMPEG_PATH, '-i', url, 'output_video.mp4'])
    209. if __name__ == "__main__":
    210. app = NajeebChannelPlayer()
    211. app.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 によって変換されたページ (->オリジナル) /