Licence des Projets
Code YT_install V1.3

YT_install V1.3 est un outil conçu pour installer du contenu audio et vidéo provenant de YouTube Il permet de récupérer de la musique ou des vidéos à partir d’un lien YouTube ou d’une playlist

Il suffit de fournir l’URL du contenu souhaité et le programme s’occupe du reste automatiquement

L’objectif de cet outil est de simplifier l’accès à vos contenus favoris en les rendant disponibles localement sur votre appareil

yt_install.exe est conçu pour être simple d’utilisation et efficace afin de proposer une expérience rapide et intuitive

Code OutSond V1.2

Qu’est-ce que Outsond.exe ?

Outsond est un lecteur audio conçu pour écouter de la musique et des podcasts en toute simplicité Le service est entièrement basé sur le son : il n’y a pas de vidéo uniquement de l’audio pour une expérience plus légère et rapide

Vous pouvez y écouter vos musiques préférées et découvrir des podcasts grâce à un lecteur optimisé pour la performance et la simplicité d’utilisation Outsond a été optimisé pour ce fonctionnement afin d’offrir une expérience fluide, rapide et centrée uniquement sur l’audio

L’objectif est de proposer une interface simple, efficace et accessible, sans éléments inutiles Pour utiliser Outsond, vous devez installer vos musiques ou podcasts via l'outil
YT_Install.exe

Code Ultra Booster V9

Code YT_install V2

comming soon

Code Menu_Installer.py

Code Installer_Vidéo.pyw

Code Installer_Music.pyw




import os
import time
from yt_dlp import YoutubeDL
tm = time.sleep
so = os.system

def main():
    so("cls")
    print(f"retourner au menu = 0")
    ds= input("Dossier de sortie (default = downloads) : ").strip()

    if ds.lower() == "0":
        import menu_installer
        menu_installer.menu()
        return

    if ds.startswith("http"):
        print("❌ Tu as mis une URL au lieu d'un dossier.")
        return

    if not ds:
        ds = "downloads"
    os.makedirs(ds, exist_ok=True)
    output_template = os.path.join(ds, "%(title)s.%(ext)s")
    while True:
        so("cls")
        print(f"retourner au menu = 0")
        print("\n - installer musique youtube - ")
        url = input("URL (exit pour quitter) : ").strip()

        if url == "0":
            import menu_installer
            menu_installer.menu()
            return

        if not url.startswith("http"):
            print("❌ URL invalide")
            tm(2)
            so("cls")
            continue

        opts = {
            "format": "bestaudio",
            "outtmpl": output_template,
        }

        with YoutubeDL(opts) as ydl:
            ydl.download([url])

        input("\n✔ Terminé. Appuie sur Entrée pour continuer...")
        os.system("cls")
                 
pour pouvoir voir le code source cliquer sur un des panneaux si dessous et après appuyer sur le bouton allez voir
mes réseaux Discord Tiktok Youtube
Code gui.pyw


import os
import sys
import traceback
import tkinter as tk
import vlc

import next as nxt
import outsond as snd
import autonext as auto
import addtime as timectrl
import ch_fl_ds as chooser

os.chdir(os.path.dirname(os.path.abspath(__file__)))

class Player:
    def __init__(self, root):
        self.root = root
        self.root.title("OutSound Player")
        self.root.geometry("900x520")
        self.root.resizable(False, False)
        self.root.configure(bg="#0f0f14")

        self.instance = vlc.Instance()
        self.player = self.instance.media_player_new()

        self.playlist = []
        self.index = -1

        nxt.bind(self)
        snd.bind(self)
        auto.bind(self)
        timectrl.bind(self)

        self.canvas = tk.Canvas(
            root,
            bg="#0f0f14",
            highlightthickness=0
        )
        self.canvas.pack(fill="both", expand=True)

        self.panel = tk.Frame(
            self.canvas,
            bg="#141420"
        )
        self.panel.place(relx=0.5, rely=0.5, anchor="center", width=820, height=440)

        self.title = tk.Label(
            self.panel,
            text="OUTSOUND PLAYER",
            bg="#141420",
            fg="#ffffff",
            font=("Arial", 18, "bold")
        )
        self.title.pack(pady=15)

        self.btn_load = tk.Button(
            self.panel,
            text="Choisir musique / dossier",
            command=self.load_media,
            bg="#2b2b40",
            fg="white",
            activebackground="#3a3a55",
            activeforeground="white",
            relief="flat",
            width=25,
            height=2
        )
        self.btn_load.pack(pady=10)

        self.btn_play = tk.Button(
            self.panel,
            text="▶ PLAY",
            width=15,
            height=2,
            bg="#1f6feb",
            fg="white",
            activebackground="#2b7cff",
            relief="flat",
            command=self.toggle_play
        )
        self.btn_play.pack(pady=15)

        controls = tk.Frame(self.panel, bg="#141420")
        controls.pack(pady=10)

        self.btn_prev = tk.Button(
            controls,
            text="⏮",
            width=5,
            command=nxt.prev_song,
            bg="#2b2b40",
            fg="white",
            relief="flat"
        )
        self.btn_prev.pack(side="left", padx=10)

        self.btn_next = tk.Button(
            controls,
            text="⏭",
            width=5,
            command=nxt.next_song,
            bg="#2b2b40",
            fg="white",
            relief="flat"
        )
        self.btn_next.pack(side="left", padx=10)

        self.btn_back = tk.Button(
            controls,
            text="-10s",
            width=5,
            command=timectrl.sub_10s,
            bg="#2b2b40",
            fg="white",
            relief="flat"
        )
        self.btn_back.pack(side="left", padx=10)

        self.btn_forward = tk.Button(
            controls,
            text="+10s",
            width=5,
            command=timectrl.add_10s,
            bg="#2b2b40",
            fg="white",
            relief="flat"
        )
        self.btn_forward.pack(side="left", padx=10)

        self.btn_mute = tk.Button(
            self.panel,
            text="MUTE",
            command=snd.toggle_mute,
            bg="#2b2b40",
            fg="white",
            relief="flat",
            width=10
        )
        self.btn_mute.pack(pady=10)

        self.volume = tk.Scale(
            self.panel,
            from_=0,
            to=100,
            orient="horizontal",
            label="VOLUME",
            command=snd.set_volume,
            bg="#141420",
            fg="white",
            troughcolor="#2b2b40",
            highlightthickness=0
        )
        self.volume.set(80)
        self.volume.pack(fill="x", padx=30, pady=10)

        self.label = tk.Label(
            self.panel,
            text="Aucune musique",
            bg="#141420",
            fg="#aaaaaa",
            font=("Arial", 11)
        )
        self.label.pack(pady=10)

        auto.start_monitor()

    def load_media(self):
        self.playlist = chooser.choose_media()

        if not self.playlist:
            return

        self.index = 0
        nxt.play(self.index)

    def toggle_play(self):
        if self.player.is_playing():
            self.player.pause()
            self.btn_play.config(text="▶ PLAY")
        else:
            self.player.play()
            self.btn_play.config(text="⏸ PAUSE")

if __name__ == "__main__":
    try:
        root = tk.Tk()
        app = Player(root)
        root.mainloop()

    except Exception:
        with open("error_log.txt", "w", encoding="utf-8") as f:
            f.write(traceback.format_exc())
                 
Code ch_fl_ds.pyw


import os
import tkinter as tk
from tkinter import filedialog, messagebox

from ld_ds import FolderExplorer


def select_folders(root):

    app = FolderExplorer(root)
    app.root.wait_window()

    return app.result if app.result else []


def choose_media():

    root = tk.Tk()
    root.withdraw()

    mode = messagebox.askquestion(
        "Mode",
        "Choisir un ou plusieurs dossiers = oui / des fichiers = non"
    )

    playlist = []

    exts = (
        ".webm",
        ".mp3",
        ".wav",
        ".mp4",
        ".mkv",
        ".corex"
    )

    if mode == "yes":

        folders = select_folders(root)

        for folder in folders:

            try:
                playlist.extend(
                    os.path.join(folder, f)
                    for f in os.listdir(folder)
                    if f.lower().endswith(exts)
                )

            except Exception:
                pass

    else:

        files = filedialog.askopenfilenames(
            title="Choisir un ou plusieurs fichiers",
            filetypes=[
                ("Media", "*.webm *.mp3 *.wav *.mp4 *.mkv *.corex")
            ]
        )

        playlist = list(files)

    root.destroy()
    return playlist
                 
Code ld_ds.pyw


import os
import ctypes
import tkinter as tk
from tkinter import ttk


class FolderExplorer:

    def __init__(self, master):

        self.master = master

        self.selected_folders = set()
        self.dragging = False
        self.last_item = None
        self.result = None
        self._closed = False

        self.root = tk.Toplevel(self.master)
        self.root.title("File Explorer")
        self.root.geometry("900x520")
        self.root.resizable(False, False)
        self.root.configure(bg="#1e1e1e")

        self.current_path = tk.StringVar(self.root)

        self.style = ttk.Style(self.root)
        self.style.theme_use("clam")

        self.style.configure(
            "Treeview",
            background="#252526",
            fieldbackground="#252526",
            foreground="white",
            rowheight=28
        )

        self.style.map(
            "Treeview",
            background=[("selected", "#094771")]
        )

        self.start_path = self.get_start_path()
        self.current_path.set(self.start_path)

        self.build_gui()
        self.load_directory(self.start_path)

        self.root.protocol("WM_DELETE_WINDOW", self.close)


        self.master.update_idletasks()
        self.root.deiconify()
        self.root.lift()
        self.root.focus_force()
        self.FILE_ATTRIBUTE_HIDDEN = 2
        self.FILE_ATTRIBUTE_SYSTEM = 4

    def is_hidden_or_system(self, path):
        try:
            attrs = ctypes.windll.kernel32.GetFileAttributesW(str(path))
            if attrs == -1:
                return False

            FILE_ATTRIBUTE_HIDDEN = 2
            FILE_ATTRIBUTE_SYSTEM = 4
            FILE_ATTRIBUTE_REPARSE_POINT = 1024

            return bool(
                attrs & (
                    FILE_ATTRIBUTE_HIDDEN |
                    FILE_ATTRIBUTE_SYSTEM |
                    FILE_ATTRIBUTE_REPARSE_POINT
                )
            )

        except:
            return False

    def close(self):

        if self._closed:
            return

        self._closed = True

        if self.result is None:
            self.result = list(self.selected_folders)

        self.selected_folders.clear()

        try:
            self.root.destroy()
        except:
            pass

    def get_start_path(self):
        return os.path.expanduser("~")

    def normalize_path(self, path):

        if not path:
            return ""

        path = path.strip().strip('"').strip("'")
        path = path.replace("/", "\\")
        return os.path.normpath(path)

    def build_gui(self):

        top = tk.Frame(self.root, bg="#1e1e1e")
        top.pack(fill="x", padx=8, pady=6)

        tk.Button(top, text="⬅", command=self.go_back,
                  bg="#2d2d30", fg="white", width=3).pack(side="left")

        self.path_entry = tk.Entry(
            top,
            textvariable=self.current_path,
            bg="#252526",
            fg="white",
            insertbackground="white"
        )
        self.path_entry.pack(side="left", fill="x", expand=True, padx=6)
        self.path_entry.bind("", self.open_path)

        tk.Button(top, text="Go", command=self.open_path,
                  bg="#2d2d30", fg="white").pack(side="left")

        tk.Button(top, text="⟳", command=self.refresh,
                  bg="#2d2d30", fg="white", width=3).pack(side="left", padx=4)

        mid = tk.Frame(self.root, bg="#1e1e1e")
        mid.pack(fill="both", expand=True, padx=8, pady=6)

        self.tree = ttk.Treeview(mid, selectmode="none")
        self.tree.pack(side="left", fill="both", expand=True)

        scroll = ttk.Scrollbar(mid, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=scroll.set)
        scroll.pack(side="right", fill="y")

        self.tree.bind("", self.open_item)
        self.tree.bind("", self.on_press)
        self.tree.bind("", self.on_drag)
        self.tree.bind("", self.on_release)

        bottom = tk.Frame(self.root, bg="#1e1e1e")
        bottom.pack(fill="x", padx=8, pady=6)

        tk.Button(
            bottom,
            text="Valider sélection",
            command=self.validate_selection,
            bg="#0078d7",
            fg="white"
        ).pack(side="right")

    def clear_selection(self):
        self.selected_folders.clear()
        self.tree.selection_remove(self.tree.selection())

    def on_press(self, event):

        item = self.tree.identify_row(event.y)

        if item:
            self.clear_selection()

        self.dragging = True

        if item:
            self.last_item = item
            self.toggle_select(item)

    def on_drag(self, event):

        if not self.dragging:
            return

        item = self.tree.identify_row(event.y)

        if item and item != self.last_item:
            self.last_item = item
            self.add_select(item)

    def on_release(self, event):
        self.dragging = False
        self.last_item = None

    def toggle_select(self, item):

        values = self.tree.item(item, "values")
        if values:
            self.selected_folders.add(values[0])
            self.tree.selection_add(item)

    def add_select(self, item):

        values = self.tree.item(item, "values")
        if values:
            self.selected_folders.add(values[0])
            self.tree.selection_add(item)

    def load_directory(self, path):

        path = self.normalize_path(path)

        if not os.path.isdir(path):
            return

        self.tree.delete(*self.tree.get_children())
        self.current_path.set(path)

        parent = os.path.dirname(path)

        if parent != path:
            self.tree.insert("", "end", text="⬅ ..", values=(parent,))

        try:
            for item in sorted(os.listdir(path), key=str.lower):
                full = os.path.join(path, item)

                if os.path.isdir(full) and not self.is_hidden_or_system(full):
                    self.tree.insert("", "end", text="📁 " + item, values=(full,))
        except:
            pass

    def open_item(self, event):

        sel = self.tree.selection()
        if sel:
            values = self.tree.item(sel[0], "values")
            if values:
                self.load_directory(values[0])

    def open_path(self, event=None):

        path = self.normalize_path(self.current_path.get())

        if os.path.isdir(path):
            self.load_directory(path)

    def refresh(self):
        self.load_directory(self.current_path.get())

    def go_back(self):

        current = self.current_path.get()
        parent = os.path.dirname(current)

        if parent != current:
            self.load_directory(parent)

    def validate_selection(self):

        if not self.selected_folders:
            self.result = []
        else:
            self.result = list(self.selected_folders)

        self.close()
                 
Code next.pyw


import os
player = None

def bind(app):
    global player
    player = app

def _safe_index(index):
    if not player or not player.playlist:
        return None

    size = len(player.playlist)

    if size == 0:
        return None

    return index % size

def play(index):
    if not player or not player.playlist:
        return

    index = _safe_index(index)
    if index is None:
        return

    path = player.playlist[index]

    try:
        media = player.instance.media_new(path)

        media.add_option("no-video")

        player.player.set_media(media)
        player.player.play()

        player.index = index

        name = os.path.splitext(os.path.basename(path))[0]
        player.label.config(text=name)

    except Exception:
        pass

def next_song():
    if not player or not player.playlist:
        return

    play(player.index + 1)

def prev_song():
    if not player or not player.playlist:
        return

    play(player.index - 1)

def replay():
    if player and player.index >= 0:
        play(player.index)
                 
Code autonext.pyw


import threading
import time
import vlc
import next as nxt
player = None
running = False
_last_trigger = 0

def bind(app):
    global player
    player = app

def monitor():
    global _last_trigger

    while running:

        if player is not None and player.player is not None:

            try:
                p = player.player
                state = p.get_state()
                length = p.get_length()
                pos = p.get_time()
                current_time = time.time()

                if length > 0 and pos > 0:

                    is_ended = (
                        state == vlc.State.Ended
                        or pos >= length - 500
                    )

                    if is_ended and (current_time - _last_trigger > 1.0):
                        _last_trigger = current_time
                        nxt.next_song()

            except Exception:
                pass

        time.sleep(0.05)

def start_monitor():
    global running

    if running:
        return

    running = True

    t = threading.Thread(
        target=monitor,
        daemon=True
    )

    t.start()
                 
Code addtime.pyw


import vlc

player = None

def bind(app):
    global player
    player = app

def _get_time():
    try:
        return player.player.get_time()
    except:
        return 0

def _get_length():
    try:
        return player.player.get_length()
    except:
        return 0

def add_10s():
    if player is None:
        return

    try:
        current = _get_time()
        length = _get_length()

        if length <= 0:
            return

        new_time = current + 10000

        if new_time > length:
            new_time = length

        player.player.set_time(int(new_time))

    except:
        pass

def sub_10s():
    if player is None:
        return

    try:
        current = _get_time()
        new_time = current - 10000

        if new_time < 0:
            new_time = 0

        player.player.set_time(int(new_time))

    except:
        pass
                 
Code outsond.pyw


player = None
muted = False

def bind(app):
    global player
    player = app

def apply_volume(volume):
    if player is None:
        return

    if volume is None:
        return

    try:
        player.player.audio_set_volume(volume)
    except:
        pass

    try:
        if hasattr(player, "volume"):
            player.volume.set(volume)
    except:
        pass

def set_volume(val):
    global user_volume

    if player is None:
        return

    try:
        volume = int(float(val))
    except:
        return

    volume = max(0, min(100, volume))
    user_volume = volume
    apply_volume(volume)

def toggle_mute():
    global muted

    if player is None:
        return

    muted = not muted

    try:
        if muted:
            player.player.audio_set_volume(0)
            player.btn_mute.config(text="Unmute")
        else:
            if user_volume is not None:
                player.player.audio_set_volume(user_volume)
            player.btn_mute.config(text="Mute")
    except:
        pass