E-Stim Player

import tkinter as tk
from tkinter import filedialog, ttk
import vlc
import os
import time
import subprocess

class VLCVideoPlayer:
    # Main class for the video/audio player using VLC and Tkinter
    def __init__(self, root):
        self.root = root
        self.root.title("E-Stim Player")

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

        self.audio_instance = vlc.Instance()
        self.audio_player = self.audio_instance.media_player_new()
        self.audio_media = None

        self.audio_device_map = {}
        self.selected_audio_device_id = None

        self.video_media = None
        self.slider_dragging = False
        self.was_playing_before_drag = False
        self.is_paused = True
        self.fullscreen = False

        self.main_frame = tk.Frame(self.root)
        self.main_frame.pack(fill=tk.BOTH, expand=1)

        self.create_menu()
        self.create_toolbar()
        self.create_video_frame()
        self.create_controls()

        self.root.bind("<f>", lambda e: self.toggle_fullscreen())
        self.update_slider()
        self.root.bind("<Left>", lambda e: self.seek_relative(-5))
        self.root.bind("<Right>", lambda e: self.seek_relative(5))
        self.root.bind("<m>", lambda e: self.toggle_mute())
        self.root.bind("<q>", lambda e: self.root.quit())
        self.root.bind("<space>", lambda e: self.toggle_play_pause())

    def create_menu(self):
        self.menubar = tk.Menu(self.root)

        file_menu = tk.Menu(self.menubar, tearoff=0)
        file_menu.add_command(label="Open Video", command=self.open_video)
        file_menu.add_command(label="Select Audio", command=self.select_audio_file)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self.root.quit)
        self.menubar.add_cascade(label="File", menu=file_menu)

        setup_menu = tk.Menu(self.menubar, tearoff=0)
        setup_menu.add_command(label="System Audio Settings", command=self.open_audio_settings)
        self.menubar.add_cascade(label="Setup", menu=setup_menu)

        self.root.config(menu=self.menubar)

    def create_toolbar(self):
        self.toolbar = tk.Frame(self.main_frame, bd=1, relief=tk.RAISED)

        tk.Button(self.toolbar, text="📂 Select Video", command=self.open_video).pack(side=tk.LEFT, padx=2, pady=2)
        tk.Button(self.toolbar, text="🎵 Select Audio", command=self.select_audio_file).pack(side=tk.LEFT, padx=2, pady=2)
        tk.Button(self.toolbar, text="⛶ Full Screen", command=self.toggle_fullscreen).pack(side=tk.LEFT, padx=2, pady=2)

        tk.Label(self.toolbar, text="Audio Device:").pack(side=tk.LEFT, padx=5)

        self.audio_combo = ttk.Combobox(self.toolbar, state="readonly", width=30)
        self.audio_combo.pack(side=tk.LEFT, padx=2)
        self.audio_combo.bind("<<ComboboxSelected>>", self.on_audio_device_selected)

        self.volume_slider = tk.Scale(self.toolbar, from_=0, to=100, orient=tk.HORIZONTAL, length=200, showvalue=0, command=self.set_audio_volume)
        self.volume_slider.set(100)
        self.volume_slider.pack(side=tk.LEFT, padx=5)

        self.mute_button = tk.Button(self.toolbar, text="🔇 Mute", command=self.toggle_mute)
        self.mute_button.pack(side=tk.LEFT, padx=5)

        self.toolbar.pack(side=tk.TOP, fill=tk.X)
        self.populate_audio_devices()

    def populate_audio_devices(self):
        outputs = self.audio_player.audio_output_device_enum()
        devices = []
        while outputs:
            name = outputs.contents.device
            desc = outputs.contents.description
            if name and desc:
                name_str = name.decode()
                desc_str = desc.decode()
                self.audio_device_map[desc_str] = name_str
                devices.append(desc_str)
            outputs = outputs.contents.next
        self.audio_combo['values'] = devices
        if devices:
            self.audio_combo.current(0)
            self.selected_audio_device_id = self.audio_device_map[devices[0]]

    def on_audio_device_selected(self, event):
        selected = self.audio_combo.get()
        self.selected_audio_device_id = self.audio_device_map.get(selected, None)

    def set_audio_volume(self, val):
        if not self.audio_player.audio_get_mute():
            self.audio_player.audio_set_volume(int(val))
        self.audio_player.audio_set_volume(int(val))

    def create_video_frame(self):
        self.video_panel = tk.Frame(self.main_frame, bg="black")
        self.video_panel.pack(fill=tk.BOTH, expand=1)
        self.set_video_output()

    def set_video_output(self):
        self.root.update()
        if os.name == "nt":
            self.player.set_hwnd(self.video_panel.winfo_id())
        else:
            self.player.set_xwindow(self.video_panel.winfo_id())

    def create_controls(self):
        self.control_frame = tk.Frame(self.main_frame)

        self.slider = tk.Scale(self.control_frame, from_=0, to=1000, orient=tk.HORIZONTAL, showvalue=0, command=self.on_slider_move)
        self.slider.pack(fill=tk.X, expand=1, padx=5)

        self.slider.bind("<ButtonPress-1>", self.on_slider_click)
        self.slider.bind("<ButtonRelease-1>", self.on_slider_release)

        self.btns = tk.Frame(self.control_frame)
        self.btn_play = tk.Button(self.btns, text="▶ Play", command=self.toggle_play_pause)
        self.btn_play.pack(side=tk.LEFT, padx=5)

        self.btn_stop = tk.Button(self.btns, text="■ Stop", command=self.stop)
        self.btn_stop.pack(side=tk.LEFT, padx=5)

        self.btns.pack(pady=5)
        self.control_frame.pack(fill=tk.X)

    def open_video(self):
        self.stop()
        path = filedialog.askopenfilename(filetypes=[("Video files", "*.mp4 *.avi *.mkv *.mov")])
        if not path:
            return
        self.video_media = self.instance.media_new(path)
        self.player.set_media(self.video_media)
        self.btn_play.config(text="▶ Play")
        self.is_paused = True

    def select_audio_file(self):
        self.stop()
        path = filedialog.askopenfilename(filetypes=[("Audio files", "*.mp3 *.wav *.ogg *.aac")])
        if not path:
            return
        self.audio_media = self.audio_instance.media_new(path)
        self.audio_player.set_media(self.audio_media)

        self.audio_player.play()
        time.sleep(0.1)
        self.audio_player.pause()

        if self.selected_audio_device_id:
            self.audio_player.audio_output_device_set(None, self.selected_audio_device_id)
        self.audio_player.audio_set_volume(self.volume_slider.get())

    def toggle_play_pause(self):
        if not self.video_media and not self.audio_media:
            return

        if self.is_paused:
            if self.video_media:
                self.player.play()
            if self.audio_media:
                if self.audio_player.get_state() == vlc.State.Stopped:
                    self.audio_player.set_media(self.audio_media)
                    if self.selected_audio_device_id:
                        self.audio_player.audio_output_device_set(None, self.selected_audio_device_id)
                    self.audio_player.audio_set_volume(self.volume_slider.get())
                self.audio_player.play()
            self.btn_play.config(text="⏸ Pause")
            self.is_paused = False
        else:
            if self.video_media:
                self.player.pause()
            if self.audio_media:
                self.audio_player.pause()
            self.btn_play.config(text="▶ Play")
            self.is_paused = True

    def stop(self):
        if self.video_media:
            self.player.stop()
        if self.audio_media:
            self.audio_player.pause()
            self.audio_player.set_position(0)
        self.slider.set(0)
        self.btn_play.config(text="▶ Play")
        self.is_paused = True

    def on_slider_move(self, val):
        if self.slider_dragging:
            pos = float(val) / 1000
            if self.video_media:
                self.player.set_position(pos)
            if self.audio_media:
                self.audio_player.set_position(pos)

    def on_slider_click(self, event):
        self.slider_dragging = True
        self.was_playing_before_drag = not self.is_paused
        widget = event.widget
        width = widget.winfo_width()
        click_x = event.x
        ratio = click_x / width
        new_val = int(ratio * 1000)
        self.slider.set(new_val)
        pos = float(new_val) / 1000
        if self.video_media:
            self.player.set_position(pos)
            if not self.is_paused:
                self.player.pause()
        if self.audio_media:
            self.audio_player.set_position(pos)
            if not self.is_paused:
                self.audio_player.pause()

    def on_slider_release(self, event):
        self.slider_dragging = False
        pos = float(self.slider.get()) / 1000
        if self.video_media:
            self.player.set_position(pos)
        if self.audio_media:
            self.audio_player.set_position(pos)
        if self.was_playing_before_drag:
            if self.video_media:
                self.player.play()
            if self.audio_media:
                self.audio_player.play()

    def seek_relative(self, seconds):
        if self.player.get_length() > 0:
            pos = self.player.get_time() + int(seconds * 1000)
            pos = max(0, min(pos, self.player.get_length()))
            self.player.set_time(pos)
            if self.audio_media:
                self.audio_player.set_time(pos)

    def toggle_fullscreen(self):
        self.fullscreen = not self.fullscreen
        self.root.attributes("-fullscreen", self.fullscreen)

        if self.fullscreen:
            self.toolbar.pack_forget()
            self.control_frame.pack_forget()
            self.video_panel.pack_forget()

            self.root.config(menu=tk.Menu())
            self.video_panel.pack(fill=tk.BOTH, expand=1)
            self.root.update()
            self.set_video_output()

        else:
            self.video_panel.pack_forget()
            self.toolbar.pack(side=tk.TOP, fill=tk.X)
            self.video_panel.pack(fill=tk.BOTH, expand=1)
            self.control_frame.pack(fill=tk.X)
            self.root.config(menu=self.menubar)
            self.root.update()
            self.set_video_output()

    def update_slider(self):
        if self.player and self.player.get_length() > 0 and not self.slider_dragging:
            pos = self.player.get_position()
            if 0 <= pos <= 1:
                self.slider.set(int(pos * 1000))
            if pos >= 0.99:
                self.stop()
        self.root.after(500, self.update_slider)

    def toggle_mute(self):
        muted = self.audio_player.audio_get_mute()
        self.audio_player.audio_toggle_mute()
        self.mute_button.config(text="🔉 Unmute" if muted else "🔇 Mute")

    def open_audio_settings(self):
        if os.name == "nt":
            subprocess.Popen(["control", "mmsys.cpl"])

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("1000x600")
    app = VLCVideoPlayer(root)
    root.mainloop()

Okay, it took me a while, but it works on Windows..

  • have python 3 on your system
  • select a directory and do the following:
    • create a file with the code (<file_name.py>)
    • run pip install python-vlc
    • run python -c "import vlc; print(vlc.libvlc_get_version())" // tells your python version 32/64bit
  • download and install VLC with the same bitness
  • add the directory to your environment variables
    • now if in a terminal you run vlc it should open up vlc
    • you might have to open a new terminal for it to register
  • now you should be able to run the script
    • go back to your directory and run python <file_name.py>

if you get import error for tk/tkinter you have to install python3-tk as well

Your video audio will be on the default output and the selected audio will be on the selected audio device.

Have fun!

Edit:

I made some changes since sometimes the stim audio is on the video but you probably do not want to change your default output to be the one you use for stimming.
Now you have control over both audio

import tkinter as tk
from tkinter import filedialog, ttk
import vlc
import os
import subprocess
import time

HOVER_ZONE_PX = 50       # pixels from bottom where hover will show controls
APPLY_DELAY_MS = 200     # delay before applying device/volume after play()

class VLCVideoPlayer:
    def __init__(self, root):
        self.root = root
        self.root.title("E-Stim Player")

        # Separate VLC instances for video and audio
        self.video_inst   = vlc.Instance()
        self.video_player = self.video_inst.media_player_new()
        self.audio_inst   = vlc.Instance()
        self.audio_player = self.audio_inst.media_player_new()

        # State
        self.video_media   = None
        self.audio_media   = None
        self.video_device_map = {}
        self.audio_device_map = {}
        self.selected_video_device = None
        self.selected_audio_device = None

        # UI flags
        self.is_paused        = True
        self.fullscreen       = False
        self.controls_visible = True

        # Build UI
        self.main_frame = tk.Frame(root)
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        self._create_menu()
        self._create_toolbar()
        self._create_video_panel()
        self._create_controls()

        # Populate devices
        self._populate_device_lists()

        # Init outputs
        if self.selected_video_device:
            self.video_player.audio_output_device_set(None, self.selected_video_device)
        if self.selected_audio_device:
            self.audio_player.audio_output_device_set(None, self.selected_audio_device)

        # Init volume UI
        for p, slider, btn in (
            (self.video_player, self.vid_vol, self.vid_mute),
            (self.audio_player, self.aud_vol, self.aud_mute),
        ):
            p.audio_set_volume(100)
            p.audio_set_mute(False)
            slider.set(100)
            btn.config(text="🔉")

        # Global hover & keys
        root.bind("<Motion>", self._on_panel_hover)
        root.bind("f",       lambda e: self._toggle_fullscreen())
        root.bind("m",       lambda e: self._toggle_audio_mute())
        root.bind("v",       lambda e: self._toggle_video_mute())
        root.bind("<Left>",  lambda e: self._seek_relative(-5))
        root.bind("<Right>", lambda e: self._seek_relative(5))
        root.bind("<space>", lambda e: self._toggle_play_pause())
        root.bind("q",       lambda e: root.quit())

        self._update_slider()

    def _create_menu(self):
        self.menubar = tk.Menu(self.root)
        filem = tk.Menu(self.menubar, tearoff=0)
        filem.add_command(label="Open Video",   command=self._open_video)
        filem.add_command(label="Select Audio", command=self._open_audio)
        filem.add_separator()
        filem.add_command(label="Exit",         command=self.root.quit)
        self.menubar.add_cascade(label="File", menu=filem)
        setup = tk.Menu(self.menubar, tearoff=0)
        setup.add_command(label="Audio Settings", command=self._open_audio_settings)
        self.menubar.add_cascade(label="Setup", menu=setup)
        self.root.config(menu=self.menubar)

    def _create_toolbar(self):
        self.toolbar = tk.Frame(self.main_frame, bd=1, relief=tk.RAISED)
        # Video controls
        tk.Button(self.toolbar, text="📂", command=self._open_video).pack(side=tk.LEFT, padx=2)
        tk.Label(self.toolbar, text="Vid Dev:").pack(side=tk.LEFT, padx=(10,2))
        self.video_combo = ttk.Combobox(self.toolbar, state="readonly", width=25)
        self.video_combo.pack(side=tk.LEFT, padx=2)
        self.video_combo.bind("<<ComboboxSelected>>", self._on_video_device)
        tk.Label(self.toolbar, text="Vol:").pack(side=tk.LEFT, padx=(10,2))
        self.vid_vol = tk.Scale(self.toolbar, from_=0, to=100,
                                orient=tk.HORIZONTAL, length=120, showvalue=0,
                                command=self._on_video_volume_change)
        self.vid_vol.pack(side=tk.LEFT)
        self.vid_mute = tk.Button(self.toolbar, text="🔇", command=self._toggle_video_mute)
        self.vid_mute.pack(side=tk.LEFT, padx=5)
        # Audio controls
        tk.Button(self.toolbar, text="🎵", command=self._open_audio).pack(side=tk.LEFT, padx=10)
        tk.Label(self.toolbar, text="Aud Dev:").pack(side=tk.LEFT, padx=(10,2))
        self.audio_combo = ttk.Combobox(self.toolbar, state="readonly", width=25)
        self.audio_combo.pack(side=tk.LEFT, padx=2)
        self.audio_combo.bind("<<ComboboxSelected>>", self._on_audio_device)
        tk.Label(self.toolbar, text="Vol:").pack(side=tk.LEFT, padx=(10,2))
        self.aud_vol = tk.Scale(self.toolbar, from_=0, to=100,
                                orient=tk.HORIZONTAL, length=120, showvalue=0,
                                command=self._on_audio_volume_change)
        self.aud_vol.pack(side=tk.LEFT)
        self.aud_mute = tk.Button(self.toolbar, text="🔇", command=self._toggle_audio_mute)
        self.aud_mute.pack(side=tk.LEFT, padx=5)
        # Fullscreen toggle
        tk.Button(self.toolbar, text="⛶", command=self._toggle_fullscreen).pack(side=tk.RIGHT, padx=5)
        self.toolbar.pack(side=tk.TOP, fill=tk.X)

    def _create_video_panel(self):
        self.video_panel = tk.Frame(self.main_frame, bg="black")
        self.video_panel.pack(fill=tk.BOTH, expand=True)
        self._attach_video_output()

    def _create_controls(self):
        self.controls_frame = tk.Frame(self.main_frame)
        self.slider = tk.Scale(self.controls_frame, from_=0, to=1000,
                               orient=tk.HORIZONTAL, showvalue=0)
        self.slider.pack(fill=tk.X, expand=True, padx=5)
        self.slider.bind("<Button-1>",        self._on_slider_click)
        self.slider.bind("<B1-Motion>",       self._on_slider_click)
        self.slider.bind("<ButtonRelease-1>", self._on_slider_end)
        btnf = tk.Frame(self.controls_frame)
        self.play_btn = tk.Button(btnf, text="▶ Play", command=self._toggle_play_pause)
        self.play_btn.pack(side=tk.LEFT, padx=5)
        self.stop_btn = tk.Button(btnf, text="■ Stop", command=self._stop)
        self.stop_btn.pack(side=tk.LEFT)
        btnf.pack(pady=5)
        self.controls_frame.pack(side=tk.BOTTOM, fill=tk.X)

    def _populate_device_lists(self):
        # Video devices
        vouts = self.video_player.audio_output_device_enum()
        video_devs = []
        while vouts:
            desc = vouts.contents.description.decode()
            video_devs.append(desc)
            self.video_device_map[desc] = vouts.contents.device.decode()
            vouts = vouts.contents.next
        self.video_combo['values'] = video_devs
        if video_devs:
            self.video_combo.current(0)
            self.selected_video_device = self.video_device_map[video_devs[0]]
        # Audio devices
        aouts = self.audio_player.audio_output_device_enum()
        audio_devs = []
        while aouts:
            desc = aouts.contents.description.decode()
            audio_devs.append(desc)
            self.audio_device_map[desc] = aouts.contents.device.decode()
            aouts = aouts.contents.next
        self.audio_combo['values'] = audio_devs
        if audio_devs:
            self.audio_combo.current(0)
            self.selected_audio_device = self.audio_device_map[audio_devs[0]]

    def _open_video(self):
        self._stop()
        path = filedialog.askopenfilename(filetypes=[("Video","*.mp4 *.avi *.mkv *.mov")])
        if not path: return
        self.video_media = self.video_inst.media_new(path)
        self.video_player.set_media(self.video_media)
        self.video_player.play(); time.sleep(0.1); self.video_player.pause()

    def _open_audio(self):
        self._stop()
        path = filedialog.askopenfilename(filetypes=[("Audio","*.mp3 *.wav *.ogg *.aac")])
        if not path: return
        self.audio_media = self.audio_inst.media_new(path)
        self.audio_player.set_media(self.audio_media)
        self.audio_player.play(); time.sleep(0.1); self.audio_player.pause()

    def _on_slider_click(self, event):
        w = event.widget
        ratio = max(0.0, min(event.x / w.winfo_width(), 1.0))
        if self.video_media:
            self.video_player.set_position(ratio)
        if self.audio_media:
            self.audio_player.set_position(ratio)
        self.slider.set(int(ratio * 1000))

    def _on_slider_end(self, event):
        if not self.is_paused:
            if self.video_media:
                self.video_player.play()
                self.root.after(APPLY_DELAY_MS, self._apply_video_settings)
            if self.audio_media:
                self.audio_player.play()
                self.root.after(APPLY_DELAY_MS, self._apply_audio_settings)

    def _on_video_device(self, _):
        new_dev = self.video_device_map[self.video_combo.get()]
        self.selected_video_device = new_dev
        cur = self.video_player.audio_output_device_get()
        if cur != new_dev:
            self.video_player.audio_output_device_set(None, new_dev)

    def _on_audio_device(self, _):
        new_dev = self.audio_device_map[self.audio_combo.get()]
        self.selected_audio_device = new_dev
        cur = self.audio_player.audio_output_device_get()
        if cur != new_dev:
            self.audio_player.audio_output_device_set(None, new_dev)

    def _on_video_volume_change(self, v):
        vol = int(v)
        if self.selected_video_device:
            cur = self.video_player.audio_output_device_get()
            if cur != self.selected_video_device:
                self.video_player.audio_output_device_set(None, self.selected_video_device)
        if self.video_player.audio_get_volume() != vol:
            self.video_player.audio_set_volume(vol)

    def _on_audio_volume_change(self, v):
        vol = int(v)
        if self.selected_audio_device:
            cur = self.audio_player.audio_output_device_get()
            if cur != self.selected_audio_device:
                self.audio_player.audio_output_device_set(None, self.selected_audio_device)
        if self.audio_player.audio_get_volume() != vol:
            self.audio_player.audio_set_volume(vol)

    def _toggle_play_pause(self):
        if not (self.video_media or self.audio_media): return
        if self.is_paused:
            if self.video_media:
                self.video_player.play()
                self.root.after(APPLY_DELAY_MS, self._apply_video_settings)
            if self.audio_media:
                self.audio_player.play()
                self.root.after(APPLY_DELAY_MS, self._apply_audio_settings)
            self.play_btn.config(text="⏸ Pause")
        else:
            if self.video_media: self.video_player.pause()
            if self.audio_media: self.audio_player.pause()
            self.play_btn.config(text="▶ Play")
        self.is_paused = not self.is_paused

    def _apply_video_settings(self):
        if not self.is_paused and self.selected_video_device:
            cur = self.video_player.audio_output_device_get()
            if cur != self.selected_video_device:
                self.video_player.audio_output_device_set(None, self.selected_video_device)
            self.video_player.audio_set_volume(self.vid_vol.get())

    def _apply_audio_settings(self):
        if not self.is_paused and self.selected_audio_device:
            cur = self.audio_player.audio_output_device_get()
            if cur != self.selected_audio_device:
                self.audio_player.audio_output_device_set(None, self.selected_audio_device)
            self.audio_player.audio_set_volume(self.aud_vol.get())

    def _stop(self):
        if self.video_media: self.video_player.stop()
        if self.audio_media: self.audio_player.stop()
        self.slider.set(0)
        self.play_btn.config(text="▶ Play")
        self.is_paused = True

    def _seek_relative(self, sec):
        if self.video_media and self.video_player.get_length() > 0:
            t = self.video_player.get_time() + int(sec * 1000)
            t = max(0, min(t, self.video_player.get_length()))
            self.video_player.set_time(t)
            if self.audio_media:
                self.audio_player.set_time(t)

    def _on_panel_hover(self, event):
        if not self.fullscreen:
            return
        # calculate y relative to window
        y = event.y_root - self.root.winfo_rooty()
        h = self.root.winfo_height()
        # get total controls height
        tb_h = self.toolbar.winfo_height()
        ctrl_h = self.controls_frame.winfo_height()
        total_h = tb_h + ctrl_h
        # show if in hover zone
        if y >= h - HOVER_ZONE_PX:
            if not self.controls_visible:
                self.toolbar.pack(side=tk.TOP, fill=tk.X)
                self.controls_frame.pack(side=tk.BOTTOM, fill=tk.X)
                self.controls_visible = True
        # hide if cursor above controls area
        elif y < h - total_h:
            if self.controls_visible:
                self.toolbar.pack_forget()
                self.controls_frame.pack_forget()
                self.controls_visible = False

    def _toggle_video_mute(self):
        m = self.video_player.audio_get_mute()
        self.video_player.audio_toggle_mute()
        self.vid_mute.config(text="🔉" if m else "🔇")

    def _toggle_audio_mute(self):
        m = self.audio_player.audio_get_mute()
        self.audio_player.audio_toggle_mute()
        self.aud_mute.config(text="🔉" if m else "🔇")

    def _toggle_fullscreen(self):
        self.fullscreen = not self.fullscreen
        self.root.attributes("-fullscreen", self.fullscreen)
        if self.fullscreen:
            self.root.config(menu="")
            self.toolbar.pack_forget()
            self.controls_frame.pack_forget()
            self.controls_visible = False
        else:
            self.root.config(menu=self.menubar)
            self.toolbar.pack(side=tk.TOP, fill=tk.X)
            self.video_panel.pack_forget()
            self.video_panel.pack(fill=tk.BOTH, expand=True)
            self.controls_frame.pack(side=tk.BOTTOM, fill=tk.X)
            self.controls_visible = True
        self._attach_video_output()

    def _attach_video_output(self):
        self.root.update()
        wid = self.video_panel.winfo_id()
        if os.name == "nt":
            self.video_player.set_hwnd(wid)
        else:
            self.video_player.set_xwindow(wid)

    def _update_slider(self):
        if self.video_media and not self.dragging:
            pos = self.video_player.get_position()
            if 0 <= pos <= 1:
                self.slider.set(int(pos * 1000))
            if pos >= 0.99:
                self._stop()
        self.root.after(500, self._update_slider)

    def _open_audio_settings(self):
        if os.name == "nt":
            subprocess.Popen(["control", "mmsys.cpl"])

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("1000x600")
    VLCVideoPlayer(root)
    root.mainloop()