Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import tkinter as tk
- from tkinter import ttk, filedialog, messagebox
- import requests
- import subprocess
- import threading
- import time
- import vlc
- import chardet
- from youtube_dl import YoutubeDL # or use yt-dlp
- from apiclient.discovery import build
- from pytube import YouTube
- # Constants
- YOUTUBE_API_KEY = 'AIzaSyCzS7PGThVFxD83UFbfU5DOSZBMTxNpEeA'
- YOUTUBE_API_SERVICE_NAME = 'youtube'
- YOUTUBE_API_VERSION = 'v3'
- def play_youtube_video():
- try:
- selected_channel = result_text.get(tk.ACTIVE)
- if selected_channel in channels_info:
- url = channels_info[selected_channel]
- yt = YouTube(url)
- video_url = yt.streams.filter(progressive=True, file_extension='mp4').first().url
- media = instance.media_new(video_url)
- player.set_media(media)
- player.play()
- except Exception as e:
- messagebox.showerror("Error", f"An error occurred while playing the video: {e}")
- def play_local_video(url):
- try:
- subprocess.Popen([r"C:\Program Files\VideoLAN\VLC\vlc.exe", url])
- except Exception as e:
- messagebox.showerror("Error", f"An error occurred while playing the video: {e}")
- # Functions for the main functionalities
- def search_channels():
- search_term = url_entry.get().lower()
- if search_term.startswith("http"):
- search_by_url(search_term)
- else:
- search_by_path_or_category(search_term)
- def search_by_url(url):
- try:
- if os.path.exists(url):
- with open(url, 'r', encoding='utf-8') as file:
- m3u_data = file.readlines()
- process_m3u_data(m3u_data)
- else:
- response = requests.get(url)
- if response.status_code == 200:
- try:
- m3u_data = response.text.split('\n')
- except UnicodeDecodeError:
- m3u_data = response.content.decode('ISO-8859-1').split('\n')
- process_m3u_data(m3u_data)
- else:
- result_text.insert(tk.END, f"Error: Failed to fetch channel data. Status Code: {response.status_code}\n")
- except Exception as e:
- result_text.insert(tk.END, f"Error: {str(e)}\n")
- def search_by_path_or_category(path):
- try:
- if os.path.exists(path):
- try:
- with open(path, 'r', encoding='utf-8') as file:
- m3u_data = file.readlines()
- except UnicodeDecodeError:
- with open(path, 'r', encoding='ISO-8859-1') as file:
- m3u_data = file.readlines()
- process_m3u_data(m3u_data)
- else:
- selected_category = category_var.get()
- if selected_category in category_urls:
- category_url = category_urls[selected_category]
- if category_url:
- search_by_url(category_url)
- else:
- result_text.insert(tk.END, f"Error: Category URL is not provided for {selected_category}\n")
- else:
- result_text.insert(tk.END, f"Error: Category '{selected_category}' not found\n")
- except Exception as e:
- result_text.insert(tk.END, f"Error: {str(e)}\n")
- def process_m3u_data(m3u_data):
- result_text.delete(0, tk.END)
- global channels_info
- channels_info = {}
- channel_name = None
- for line in m3u_data:
- if line.startswith('#EXTINF:'):
- channel_name = line.split(',')[-1].strip()
- elif line.startswith('http') and channel_name:
- channels_info[channel_name] = line.strip()
- result_text.insert(tk.END, channel_name)
- channel_name = None
- def search_youtube():
- query = search_entry.get()
- youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=YOUTUBE_API_KEY)
- search_response = youtube.search().list(q=query, part='id,snippet', maxResults=10).execute()
- result_text.delete(0, tk.END)
- global channels_info
- channels_info = {}
- for item in search_response['items']:
- if item['id']['kind'] == 'youtube#video':
- video_title = item['snippet']['title']
- video_id = item['id']['videoId']
- video_url = f"https://www.youtube.com/watch?v={video_id}"
- channels_info[video_title] = video_url
- result_text.insert(tk.END, video_title)
- print("Searching YouTube for:", query)
- def play_selected_channel(event):
- try:
- selected_channel = result_text.get(tk.ACTIVE)
- if selected_channel in channels_info:
- url = channels_info[selected_channel]
- if 'youtube.com' in url or 'youtu.be' in url:
- download_and_play_youtube(url)
- elif os.path.exists(url):
- subprocess.Popen([r"C:\Program Files\VideoLAN\VLC\vlc.exe", url])
- except (tk.TclError, KeyError):
- pass
- def download_and_play_youtube(url):
- ydl_opts = {'format': 'best'}
- with YoutubeDL(ydl_opts) as ydl:
- info_dict = ydl.extract_info(url, download=False)
- video_url = info_dict['url']
- subprocess.Popen([r"C:\Program Files\VideoLAN\VLC\vlc.exe", video_url])
- def check_links():
- global working_links
- working_links = {}
- for channel_name, url in channels_info.items():
- try:
- response = requests.get(url)
- if response.status_code == 200:
- working_links[channel_name] = url
- except requests.RequestException:
- pass
- result_text.delete(0, tk.END)
- for channel_name, url in working_links.items():
- result_text.insert(tk.END, f"{channel_name}: {url}\n")
- def save_working_links():
- with open("working_channels.m3u", "w", encoding="utf-8") as f:
- for channel_name, url in working_links.items():
- f.write(f"#EXTINF:-1,{channel_name}\n{url}\n")
- def filter_channels(event=None):
- keyword = search_entry.get().lower()
- result_text.delete(0, tk.END)
- for channel_name, url in channels_info.items():
- if keyword in channel_name.lower():
- result_text.insert(tk.END, channel_name)
- def browse_file():
- file_path = filedialog.askopenfilename(filetypes=[("M3U Files", "*.m3u"), ("All Files", "*.*")])
- if file_path:
- url_entry.delete(0, tk.END)
- url_entry.insert(0, file_path)
- def preview_selected_link():
- def play_media():
- selected_channel = result_text.get(tk.ACTIVE).strip()
- if selected_channel in channels_info:
- url = channels_info[selected_channel]
- media = instance.media_new(url)
- player.set_media(media)
- player.play()
- update_slider()
- else:
- messagebox.showerror("Error", "Selected text is not a valid URL.")
- threading.Thread(target=play_media).start()
- def stop_preview():
- player.stop()
- preview_frame.pack_forget()
- def capture_video():
- try:
- selected_channel = result_text.get(tk.ACTIVE).strip()
- if selected_channel in channels_info:
- url = channels_info[selected_channel]
- filename = filedialog.asksaveasfilename(defaultextension=".mp4", filetypes=[("MP4 files", "*.mp4")])
- if filename:
- command = ['ffmpeg', '-y', '-i', url, '-t', '03:55:00', '-c', 'copy', filename]
- threading.Thread(target=lambda: subprocess.run(command)).start()
- messagebox.showinfo("Capturing", f"Capturing 03:55 minutes of video to {filename}")
- else:
- messagebox.showerror("Error", "Selected text is not a valid URL.")
- except tk.TclError:
- messagebox.showerror("Error", "No text selected.")
- def record_audio():
- try:
- selected_channel = result_text.get(tk.ACTIVE).strip()
- if selected_channel in channels_info:
- url = channels_info[selected_channel]
- filename = filedialog.asksaveasfilename(defaultextension=".mp3", filetypes=[("MP3 files", "*.mp3")])
- if filename:
- command = ['ffmpeg', '-y', '-i', url, '-f', 'mp3', '-c:a', 'libmp3lame', filename]
- global process
- process = subprocess.Popen(command)
- messagebox.showinfo("Recording", f"Recording audio to {filename}")
- else:
- messagebox.showerror("Error", "Selected text is not a valid URL.")
- except tk.TclError:
- messagebox.showerror("Error", "No text selected.")
- def stop_recording():
- if process:
- process.terminate()
- messagebox.showinfo("Stopped", "Recording stopped")
- def capture_screenshots():
- if player.get_media():
- filename_base = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png")])
- if filename_base:
- interval = 5
- num_screenshots = 5
- for i in range(num_screenshots):
- time.sleep(interval)
- filename = f"{filename_base}_{i+1}.png"
- player.video_take_snapshot(0, filename, 0, 0)
- messagebox.showinfo("Captured", f"Screenshot {i+1} saved to {filename}")
- def update_slider():
- if player.get_media():
- length = player.get_length() / 1000
- position = player.get_time() / 1000
- if length > 0:
- slider.set(position / length * 100)
- root.after(1000, update_slider)
- def set_position(event):
- if player.get_media():
- length = player.get_length() / 1000
- player.set_time(int(slider.get() / 100 * length * 1000))
- def on_configure(event):
- if event.widget == canvas:
- player.set_hwnd(canvas.winfo_id())
- #def toggle_mute():
- #is_muted = player.audio_get_mute()
- #player.audio_set_mute(not is_muted)
- def play_video(self):
- if self.lst.curselection():
- title = self.lst.get(self.lst.curselection())
- video_url = self.video_urls.get(title) # Get URL from dictionary
- print("Playing video:", video_url) # Print URL for debugging
- try:
- # Use pytube to get the video URL
- yt = YouTube(video_url)
- video_url = yt.streams.filter(progressive=True, file_extension='mp4').first().url
- media = self.instance.media_new(video_url)
- self.player.set_media(media)
- self.player.set_hwnd(self.player_frame.winfo_id())
- self.player.play()
- self.current_video_label.config(text=f"Playing: {title}")
- except AgeRestrictedError:
- print("Age restricted video:", video_url)
- webbrowser.open(video_url) # Open age-restricted videos in the default web browser
- except Exception as e:
- print("Error:", e)
- self.current_video_label.config(text="An error occurred while playing the video.")
- else:
- print("No video selected.")
- def set_volume(value):
- player.audio_set_volume(int(value))
- # GUI setup
- root = tk.Tk()
- root.title("Najeeb IPTV Channel Link Checker")
- root.configure(bg="#4a4a4a")
- url_frame = tk.Frame(root, bg="#4a4a4a")
- url_frame.pack(pady=10)
- url_label = tk.Label(url_frame, text="Enter URL or local path or select category:", bg="#4a4a4a", fg="white")
- url_label.pack(side=tk.LEFT, padx=5)
- url_entry = tk.Entry(url_frame, width=80)
- url_entry.pack(side=tk.LEFT, padx=5)
- search_button = tk.Button(url_frame, text="Search", command=search_channels, bg="#FFA500", fg="white")
- search_button.pack(side=tk.LEFT, padx=5)
- result_label = tk.Label(root, text="Check and save working URLs in M3U file:", bg="#4a4a4a", fg="white")
- result_label.pack()
- search_frame = tk.Frame(root, bg="#4a4a4a")
- search_frame.pack()
- search_label = tk.Label(search_frame, text="Search Channel Name:", bg="#4a4a4a", fg="white")
- search_label.pack(side=tk.LEFT, padx=5)
- search_entry = tk.Entry(search_frame, width=105)
- search_entry.pack(side=tk.LEFT, padx=5)
- search_entry.bind('<KeyRelease>', filter_channels)
- scrollbar = tk.Scrollbar(root, orient=tk.VERTICAL)
- scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
- result_text = tk.Listbox(root, height=12, width=160, yscrollcommand=scrollbar.set)
- result_text.pack()
- scrollbar.config(command=result_text.yview)
- result_text.bind("<Double-1>", play_selected_channel)
- check_button = tk.Button(root, text="Check Links", command=check_links, bg="#008000", fg="white")
- check_button.pack(side=tk.RIGHT, padx=5)
- save_button = tk.Button(root, text="Save Working Links", command=save_working_links, bg="#FF0000", fg="white")
- save_button.pack(side=tk.LEFT, padx=5)
- category_urls = {
- "NAJEEB-IPTV": "",
- "ALL-INDEX": "https://iptv-org.github.io/iptv/index.m3u",
- "CATEGORY": "https://iptv-org.github.io/iptv/index.category.m3u",
- "LANGUAGE": "https://iptv-org.github.io/iptv/index.language.m3u",
- "REGION": "https://iptv-org.github.io/iptv/index.region.m3u",
- "Brazil": "https://iptv-org.github.io/iptv/countries/br.m3u",
- "France": "https://iptv-org.github.io/iptv/countries/fr.m3u",
- "India": "https://iptv-org.github.io/iptv/countries/in.m3u",
- "Italy": "https://iptv-org.github.io/iptv/countries/it.m3u",
- "Pakistan": "https://iptv-org.github.io/iptv/countries/pk.m3u",
- "Spain": "https://iptv-org.github.io/iptv/countries/es.m3u",
- "Thailand": "https://iptv-org.github.io/iptv/countries/th.m3u",
- "UK": "https://iptv-org.github.io/iptv/countries/uk.m3u",
- "USA": "https://iptv-org.github.io/iptv/countries/us.m3u",
- "Classic": "https://iptv-org.github.io/iptv/categories/classic.m3u",
- "Comedy": "https://iptv-org.github.io/iptv/categories/comedy.m3u",
- "Documentary": "https://iptv-org.github.io/iptv/categories/documentary.m3u",
- "Entertainment": "https://iptv-org.github.io/iptv/categories/entertainment.m3u",
- "Kids": "https://iptv-org.github.io/iptv/categories/kids.m3u",
- "Movies": "https://iptv-org.github.io/iptv/categories/movies.m3u",
- "Music": "https://iptv-org.github.io/iptv/categories/music.m3u",
- "News": "https://iptv-org.github.io/iptv/categories/news.m3u",
- "Science": "https://iptv-org.github.io/iptv/categories/science.m3u",
- "Sports": "https://iptv-org.github.io/iptv/categories/sports.m3u",
- "Travel": "https://iptv-org.github.io/iptv/categories/travel.m3u",
- "PLAYLIST-1": "C:/Users/Najeeb/Desktop/IPTV/PL1.m3u",
- "PLAYLIST-2": "C:/Users/Najeeb/Desktop/IPTV/PL2.m3u",
- "PLAYLIST-3": "C:/Users/Najeeb/Desktop/IPTV/PL3.m3u",
- "PLAYLIST-4": "C:/Users/Najeeb/Desktop/IPTV/PL4.m3u",
- "PLAYLIST-5": "C:/Users/Najeeb/Desktop/IPTV/PL5.m3u",
- "PLAYLIST-6": "C:/Users/Najeeb/Desktop/IPTV/PL6.m3u",
- "PLAYLIST-R": "C:/Users/Najeeb/Desktop/IPTV/PLR.m3u",
- "PLAYLIST-X": "C:/Users/Najeeb/Desktop/IPTV/PLX.m3u",
- }
- category_var = tk.StringVar(root)
- category_var.set("NAJEEB-IPTV")
- category_dropdown = ttk.OptionMenu(root, category_var, *category_urls.keys())
- category_dropdown.pack(pady=10)
- volume_scale = tk.Scale(root, from_=0, to=100, orient="horizontal", command=set_volume, label="Volume", bg="#4a4a4a", fg="white")
- volume_scale.set(50) # Set the initial volume to 50%
- volume_scale.pack(side="left", fill="x", padx=5, pady=5)
- button_frame = tk.Frame(root, bg="#4a4a4a")
- button_frame.pack()
- browse_button = tk.Button(button_frame, text="Browse Playlist", command=browse_file, bg="#5a5a5a", fg="white")
- browse_button.pack(side=tk.LEFT, padx=5)
- preview_button = tk.Button(button_frame, text="Preview", command=preview_selected_link, bg="#5a5a5a", fg="white")
- preview_button.pack(side=tk.LEFT, padx=5)
- capture_video_button = tk.Button(button_frame, text="Capture Video", command=capture_video, bg="#5a5a5a", fg="white")
- capture_video_button.pack(side=tk.LEFT, padx=5)
- record_button = tk.Button(button_frame, text="Record Audio", command=record_audio, bg="#5a5a5a", fg="white")
- record_button.pack(side=tk.LEFT, padx=5)
- stop_button = tk.Button(button_frame, text="Stop Recording", command=stop_recording, bg="#5a5a5a", fg="white")
- stop_button.pack(side=tk.LEFT, padx=5)
- capture_screenshot_button = tk.Button(button_frame, text="Capture Screenshots", command=capture_screenshots, bg="#5a5a5a", fg="white")
- capture_screenshot_button.pack(side=tk.LEFT, padx=5)
- #toggle_mute_button = tk.Button(button_frame, text="Toggle Audio Mute", command=toggle_mute, bg="#5a5a5a", fg="white")
- #toggle_mute_button.pack(side=tk.LEFT, padx=5)
- stop_button = tk.Button(button_frame, text="Close Preview", command=stop_preview, bg="#5a5a5a", fg="white")
- stop_button.pack(side=tk.LEFT, padx=5)
- # YouTube search frame
- youtube_frame = tk.Frame(root, bg="#4a4a4a")
- youtube_frame.pack(pady=10)
- search_label = tk.Label(youtube_frame, text="Youtube search:", bg="#4a4a4a", fg="white")
- search_label.pack(side=tk.LEFT, padx=5)
- search_entry = tk.Entry(youtube_frame, width=70)
- search_entry.pack(side=tk.LEFT, padx=5)
- search_button = tk.Button(youtube_frame, text="Search", command=search_youtube, bg="#FFA500", fg="white")
- search_button.pack(side=tk.LEFT, padx=5)
- #Play
- play_button = tk.Button(youtube_frame, text="Play", command=play_youtube_video, bg="#FFA500", fg="white")
- play_button.pack(side="left", padx=5, pady=5)
- preview_frame = tk.Frame(root, bg="#4a4a4a", height=200)
- preview_frame.pack(fill="both", expand=True)
- preview_frame.pack_forget()
- canvas = tk.Canvas(preview_frame, bg="#4a4a4a")
- canvas.pack(fill="both", expand=True)
- canvas.bind("<Configure>", on_configure)
- slider = tk.Scale(preview_frame, from_=0, to=100, orient=tk.HORIZONTAL, command=set_position, bg="#4a4a4a", fg="white")
- slider.pack(fill="x", padx=5)
- instance = vlc.Instance()
- player = instance.media_player_new()
- channels_info = {}
- working_links = {}
- root.mainloop()
Add Comment
Please, Sign In to add comment