Module VLCMan

Expand source code
# ****************************************************
# Copyright: 2020 Team Visualizer (Carlos Miguel Sayao, Connor Bettermann, Issac Greenfield, Madeleine Elyea, Tanner Sundwall, Ted Moore, Prerna Agarwal)
# License: MIT
# ****************************************************
# Purpose:  Manages the VLC program.
#           Handles switching between ProjectM visualizations and video playback.
#           Handles disabling of all captions, text, and other VLC GUI elements which get in the way.
# Sources:  VLC command-line help, https://wiki.videolan.org/VLC_command-line_help
#
# ****************************************************

from subprocess import Popen, check_output, PIPE
import os
import random
from ErrorHandler import ErrorHandler
from constants import *


class VLCMan:
    def __init__(self, folder_path, playlist, entries, error_handler=None, 
                 max_duration=1800, trim_amount="600"):
        self.folder_path = folder_path  # path to folder containing videos
        self.playlist = playlist  # name of .m3u file containing playlist
        self.entries = entries  # list of video file names
        self.max_duration = max_duration  # Max duration of any given video
        self.trim_amount = trim_amount
        self.loop_status = "Playlist"
        self.eh = error_handler

    def start_vlc(self) -> bool:
        """ Boots up VLC from shell with various arguments.
        The various arguments are manipulated within the function itself.

        Args:
            None

        Returns:
            bool: True for success, False otherwise.
        """
        vlc = "vlc"
        dummy_vlc = "cvlc"
        fullscreen = "--fullscreen"
        mute = "--no-audio"
        no_title = "--no-video-title-show"
        anaglyph = "--video-filter=Anaglyph"
        disable_scroll = "--hotkeys-y-wheel-mode=-1"
        disable_mouse = "--no-mouse-events"
        cursor_timeout = "--mouse-hide-timeout=0"
        disable_network = "--no-qt-privacy-ask"
        single_instance = "--one-instance"
        loop = "--loop"
        
        if os.path.exists(self.playlist):
            try:
                # Start VLC process with specified arguments.
                # Args can be in whatever order. Only rule is that "vlc" must be at start, and "self.playlist" must be at end.
                #    Popen([dummy_vlc, anaglyph, fullscreen, mute, no_title, disable_scroll,
                #           disable_mouse, disable_network, cursor_timeout, single_instance, self.playlist])
                # For Testing, disable analglyph to check video playback
                Popen([dummy_vlc, fullscreen, mute, no_title, disable_scroll, loop,
                       disable_mouse, disable_network, cursor_timeout, single_instance, self.playlist])
                return True
            except:
                self.eh.log_critical("VLC could not properly start. Major startup error.")
                raise
        else:
            Popen([dummy_vlc, fullscreen, mute, no_title, disable_scroll, loop,
                       disable_mouse, disable_network, cursor_timeout, single_instance])
            return True

    def get_length(self, filename) -> float:
        """ Retrieve the length of a video (in seconds).

        Args:
            filename (str): Filename of video.

        Returns:
            float: Video length (in seconds).
        """
        if filename == "":
            return 0.0
        else:
            return float(check_output(["ffprobe -v error -show_entries \
                                                format=duration -of \
                                                default=noprint_wrappers=1:nokey=1 " + filename.replace(" ", "\ ")], shell=True))

    def get_length_of_current(self) -> float:
        """ Retrieves the length of the video currently being played (in seconds).

        Args:
            None

        Returns:
            float: Video length (in seconds).
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Metadata|egrep -A 1 \"vlc:length\"|cut -b 42-|egrep -v ^$"],
                     shell=True, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        return float(out) / 1000

    def get_position(self) -> float:
        """ Retrieves the current position in the video being played (in seconds).

        Args:
            None

        Returns:
            float: Video position (in seconds).
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Position|egrep -A 1 'variant'|cut -b 24-"],
                     shell=True, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        return float(out) / 1000000

    def set_position(self, track_id, position) -> bool:
        """ Sets the position of the current video.
        The track_id must be the the id of the track currently being played.

        Args:
            trackid (str): id of track to be played, gathered from get_id()
            position (float): position of video to start playing in microseconds.

        Returns:
            bool: True for success, False for failure
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetPosition objpath:" + track_id + " int64:" + str(position)], shell=True)
        return True

    def get_rate(self) -> float:
        """ Retrieve the rate the current video is being played at.

        Args:
            None

        Returns:
            float: Video rate.
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Rate|egrep -A 1 'variant'|cut -b 25-"],
                     shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
        out, err = proc.communicate()

        return float(out)

    def get_id(self) -> str:
        """ Retrieve the id of the video currently being played.
        A video's id will look something like this: "/org/videolan/vlc/playlist/5"

        Args:
            None

        Returns:
            str: Video id.
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Metadata|egrep -A 1 'mpris:trackid'|cut -b 49-|rev|cut -b 2-|rev|egrep -v ^$"],
                     shell=True, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        return out.decode('ascii').strip()

    def change_video(self, video_id):
        """ Changes the currently playing video to another video in the playlist if it exists.
        You'll need to retrieve the argument passed into this using VLCMan.get_id().
        A video's id will look something like this: "/org/videolan/vlc/playlist/5"

        Args:
            str: Video id.

        Returns:
            None
        """
        print(video_id)
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.TrackList.GoTo \
                        objpath:" + video_id], shell=True)

    def randomize_videos(self) -> bool:
        """ Randomize the order the videos populate the playlist in.
        Requires: "import random", Requires: "import os"

        Args:
            None

        Returns:
            bool: The return value. True for success, False otherwise.
        """
        # retrieve video file names and store them in a list
        self.entries = os.listdir(self.folder_path)

        # Randomize the list of video files
        random.shuffle(self.entries)
        for entry in self.entries:
            print(entry)

        return True

    def play_pause_video(self):
        """ Utilize qdbus to play/pause video.
        If the video is being played, this will pause it. If the video is 
        paused, this will play it.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause"], shell=True)

    def toggle_loop_video(self):
        """ Toggles between looping the playlist and looping the video 
        currently being played. This loop only occurs if the video hits its end 
        time. It will not occur if we manually skip to the next video.

        This option also persists until it's manually changed unlike the 
        video rate option.

        Args:
            None

        Returns:
            None
        """
        if self.loop_status == "Playlist":
            self.loop_status = "Track"
        else:
            self.loop_status = "Playlist"

        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)

    def set_loop_video(self):
        """ Set VLC to loop the current video if it's currently set to loop the playlist.

        Args:
            None

        Returns:
            None
        """
        if self.loop_status == "Playlist":
            self.loop_status = "Track"
            Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)

    def set_loop_playlist(self):
        """ Set VLC to loop the current playlist if it's currently set to loop the track.

        Args:
            None

        Returns:
            None
        """
        if self.loop_status == "Track":
            self.loop_status = "Playlist"
            Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)

    def prev_video(self):
        """ Goes back to previous video in playlist.
        Also sets the current loop status to playlist.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous"], shell=True)

    def next_video(self):
        """ Skips to next video in playlist.
        Also sets the current loop status to playlist.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next"], shell=True)

    def set_rate(self, rate):
        """ Modifies the playback rate of the video currently being played.
        This means that as soon as the video ends, the playback rate of 
        VLC will be set back to its default.

        Args:
            rate (double): playback rate.

        Returns:
            None
        """
        new_rate = self.get_rate() + rate
        if (new_rate >= RATE_MIN) and (new_rate <= RATE_MAX):
            Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                        string:org.mpris.MediaPlayer2.Player string:Rate variant:double:" + str(new_rate)], shell=True)

    def reset_rate(self):
        """ Reverts the rate the current video is being played at back to the default speed of 1.0.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:Rate variant:double:1.0"], shell=True)

    def create_playlist(self) -> bool:
        """ Writes out to .m3u file to create playlist.

            Args: 
                None

            Returns:
                bool: Returns True if creation was a success or False if failure
        """
        # open the playlist file and write to it
        f = open(self.playlist, "w")

        f.write("#EXTM3U")
        for entry in self.entries:
            f.write("\n#EXTINF:0," + entry)
            # if the duration is too long, trim the beginning and end
            if self.get_length(self.folder_path + entry) > self.max_duration:
                f.write("\n#EXTVLCOPT:start-time=" +
                        self.trim_amount + "\n#EXTVLCOPT:stop-time=600")
            f.write("\n" + self.folder_path + "/" + entry)
        f.close()
        return True

Classes

class VLCMan (folder_path, playlist, entries, error_handler=None, max_duration=1800, trim_amount='600')
Expand source code
class VLCMan:
    def __init__(self, folder_path, playlist, entries, error_handler=None, 
                 max_duration=1800, trim_amount="600"):
        self.folder_path = folder_path  # path to folder containing videos
        self.playlist = playlist  # name of .m3u file containing playlist
        self.entries = entries  # list of video file names
        self.max_duration = max_duration  # Max duration of any given video
        self.trim_amount = trim_amount
        self.loop_status = "Playlist"
        self.eh = error_handler

    def start_vlc(self) -> bool:
        """ Boots up VLC from shell with various arguments.
        The various arguments are manipulated within the function itself.

        Args:
            None

        Returns:
            bool: True for success, False otherwise.
        """
        vlc = "vlc"
        dummy_vlc = "cvlc"
        fullscreen = "--fullscreen"
        mute = "--no-audio"
        no_title = "--no-video-title-show"
        anaglyph = "--video-filter=Anaglyph"
        disable_scroll = "--hotkeys-y-wheel-mode=-1"
        disable_mouse = "--no-mouse-events"
        cursor_timeout = "--mouse-hide-timeout=0"
        disable_network = "--no-qt-privacy-ask"
        single_instance = "--one-instance"
        loop = "--loop"
        
        if os.path.exists(self.playlist):
            try:
                # Start VLC process with specified arguments.
                # Args can be in whatever order. Only rule is that "vlc" must be at start, and "self.playlist" must be at end.
                #    Popen([dummy_vlc, anaglyph, fullscreen, mute, no_title, disable_scroll,
                #           disable_mouse, disable_network, cursor_timeout, single_instance, self.playlist])
                # For Testing, disable analglyph to check video playback
                Popen([dummy_vlc, fullscreen, mute, no_title, disable_scroll, loop,
                       disable_mouse, disable_network, cursor_timeout, single_instance, self.playlist])
                return True
            except:
                self.eh.log_critical("VLC could not properly start. Major startup error.")
                raise
        else:
            Popen([dummy_vlc, fullscreen, mute, no_title, disable_scroll, loop,
                       disable_mouse, disable_network, cursor_timeout, single_instance])
            return True

    def get_length(self, filename) -> float:
        """ Retrieve the length of a video (in seconds).

        Args:
            filename (str): Filename of video.

        Returns:
            float: Video length (in seconds).
        """
        if filename == "":
            return 0.0
        else:
            return float(check_output(["ffprobe -v error -show_entries \
                                                format=duration -of \
                                                default=noprint_wrappers=1:nokey=1 " + filename.replace(" ", "\ ")], shell=True))

    def get_length_of_current(self) -> float:
        """ Retrieves the length of the video currently being played (in seconds).

        Args:
            None

        Returns:
            float: Video length (in seconds).
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Metadata|egrep -A 1 \"vlc:length\"|cut -b 42-|egrep -v ^$"],
                     shell=True, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        return float(out) / 1000

    def get_position(self) -> float:
        """ Retrieves the current position in the video being played (in seconds).

        Args:
            None

        Returns:
            float: Video position (in seconds).
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Position|egrep -A 1 'variant'|cut -b 24-"],
                     shell=True, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        return float(out) / 1000000

    def set_position(self, track_id, position) -> bool:
        """ Sets the position of the current video.
        The track_id must be the the id of the track currently being played.

        Args:
            trackid (str): id of track to be played, gathered from get_id()
            position (float): position of video to start playing in microseconds.

        Returns:
            bool: True for success, False for failure
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetPosition objpath:" + track_id + " int64:" + str(position)], shell=True)
        return True

    def get_rate(self) -> float:
        """ Retrieve the rate the current video is being played at.

        Args:
            None

        Returns:
            float: Video rate.
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Rate|egrep -A 1 'variant'|cut -b 25-"],
                     shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
        out, err = proc.communicate()

        return float(out)

    def get_id(self) -> str:
        """ Retrieve the id of the video currently being played.
        A video's id will look something like this: "/org/videolan/vlc/playlist/5"

        Args:
            None

        Returns:
            str: Video id.
        """
        proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                                string:org.mpris.MediaPlayer2.Player \
                                string:Metadata|egrep -A 1 'mpris:trackid'|cut -b 49-|rev|cut -b 2-|rev|egrep -v ^$"],
                     shell=True, stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        return out.decode('ascii').strip()

    def change_video(self, video_id):
        """ Changes the currently playing video to another video in the playlist if it exists.
        You'll need to retrieve the argument passed into this using VLCMan.get_id().
        A video's id will look something like this: "/org/videolan/vlc/playlist/5"

        Args:
            str: Video id.

        Returns:
            None
        """
        print(video_id)
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.TrackList.GoTo \
                        objpath:" + video_id], shell=True)

    def randomize_videos(self) -> bool:
        """ Randomize the order the videos populate the playlist in.
        Requires: "import random", Requires: "import os"

        Args:
            None

        Returns:
            bool: The return value. True for success, False otherwise.
        """
        # retrieve video file names and store them in a list
        self.entries = os.listdir(self.folder_path)

        # Randomize the list of video files
        random.shuffle(self.entries)
        for entry in self.entries:
            print(entry)

        return True

    def play_pause_video(self):
        """ Utilize qdbus to play/pause video.
        If the video is being played, this will pause it. If the video is 
        paused, this will play it.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause"], shell=True)

    def toggle_loop_video(self):
        """ Toggles between looping the playlist and looping the video 
        currently being played. This loop only occurs if the video hits its end 
        time. It will not occur if we manually skip to the next video.

        This option also persists until it's manually changed unlike the 
        video rate option.

        Args:
            None

        Returns:
            None
        """
        if self.loop_status == "Playlist":
            self.loop_status = "Track"
        else:
            self.loop_status = "Playlist"

        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)

    def set_loop_video(self):
        """ Set VLC to loop the current video if it's currently set to loop the playlist.

        Args:
            None

        Returns:
            None
        """
        if self.loop_status == "Playlist":
            self.loop_status = "Track"
            Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)

    def set_loop_playlist(self):
        """ Set VLC to loop the current playlist if it's currently set to loop the track.

        Args:
            None

        Returns:
            None
        """
        if self.loop_status == "Track":
            self.loop_status = "Playlist"
            Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)

    def prev_video(self):
        """ Goes back to previous video in playlist.
        Also sets the current loop status to playlist.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous"], shell=True)

    def next_video(self):
        """ Skips to next video in playlist.
        Also sets the current loop status to playlist.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next"], shell=True)

    def set_rate(self, rate):
        """ Modifies the playback rate of the video currently being played.
        This means that as soon as the video ends, the playback rate of 
        VLC will be set back to its default.

        Args:
            rate (double): playback rate.

        Returns:
            None
        """
        new_rate = self.get_rate() + rate
        if (new_rate >= RATE_MIN) and (new_rate <= RATE_MAX):
            Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                        /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                        string:org.mpris.MediaPlayer2.Player string:Rate variant:double:" + str(new_rate)], shell=True)

    def reset_rate(self):
        """ Reverts the rate the current video is being played at back to the default speed of 1.0.

        Args:
            None

        Returns:
            None
        """
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:Rate variant:double:1.0"], shell=True)

    def create_playlist(self) -> bool:
        """ Writes out to .m3u file to create playlist.

            Args: 
                None

            Returns:
                bool: Returns True if creation was a success or False if failure
        """
        # open the playlist file and write to it
        f = open(self.playlist, "w")

        f.write("#EXTM3U")
        for entry in self.entries:
            f.write("\n#EXTINF:0," + entry)
            # if the duration is too long, trim the beginning and end
            if self.get_length(self.folder_path + entry) > self.max_duration:
                f.write("\n#EXTVLCOPT:start-time=" +
                        self.trim_amount + "\n#EXTVLCOPT:stop-time=600")
            f.write("\n" + self.folder_path + "/" + entry)
        f.close()
        return True

Methods

def change_video(self, video_id)

Changes the currently playing video to another video in the playlist if it exists. You'll need to retrieve the argument passed into this using VLCMan.get_id(). A video's id will look something like this: "/org/videolan/vlc/playlist/5"

Args

str
Video id.

Returns

None
 
Expand source code
def change_video(self, video_id):
    """ Changes the currently playing video to another video in the playlist if it exists.
    You'll need to retrieve the argument passed into this using VLCMan.get_id().
    A video's id will look something like this: "/org/videolan/vlc/playlist/5"

    Args:
        str: Video id.

    Returns:
        None
    """
    print(video_id)
    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.TrackList.GoTo \
                    objpath:" + video_id], shell=True)
def create_playlist(self)

Writes out to .m3u file to create playlist.

Args: None

Returns

bool
Returns True if creation was a success or False if failure
Expand source code
def create_playlist(self) -> bool:
    """ Writes out to .m3u file to create playlist.

        Args: 
            None

        Returns:
            bool: Returns True if creation was a success or False if failure
    """
    # open the playlist file and write to it
    f = open(self.playlist, "w")

    f.write("#EXTM3U")
    for entry in self.entries:
        f.write("\n#EXTINF:0," + entry)
        # if the duration is too long, trim the beginning and end
        if self.get_length(self.folder_path + entry) > self.max_duration:
            f.write("\n#EXTVLCOPT:start-time=" +
                    self.trim_amount + "\n#EXTVLCOPT:stop-time=600")
        f.write("\n" + self.folder_path + "/" + entry)
    f.close()
    return True
def get_id(self)

Retrieve the id of the video currently being played. A video's id will look something like this: "/org/videolan/vlc/playlist/5"

Args

None
 

Returns

str
Video id.
Expand source code
def get_id(self) -> str:
    """ Retrieve the id of the video currently being played.
    A video's id will look something like this: "/org/videolan/vlc/playlist/5"

    Args:
        None

    Returns:
        str: Video id.
    """
    proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                            /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                            string:org.mpris.MediaPlayer2.Player \
                            string:Metadata|egrep -A 1 'mpris:trackid'|cut -b 49-|rev|cut -b 2-|rev|egrep -v ^$"],
                 shell=True, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    return out.decode('ascii').strip()
def get_length(self, filename)

Retrieve the length of a video (in seconds).

Args

filename : str
Filename of video.

Returns

float
Video length (in seconds).
Expand source code
def get_length(self, filename) -> float:
    """ Retrieve the length of a video (in seconds).

    Args:
        filename (str): Filename of video.

    Returns:
        float: Video length (in seconds).
    """
    if filename == "":
        return 0.0
    else:
        return float(check_output(["ffprobe -v error -show_entries \
                                            format=duration -of \
                                            default=noprint_wrappers=1:nokey=1 " + filename.replace(" ", "\ ")], shell=True))
def get_length_of_current(self)

Retrieves the length of the video currently being played (in seconds).

Args

None
 

Returns

float
Video length (in seconds).
Expand source code
def get_length_of_current(self) -> float:
    """ Retrieves the length of the video currently being played (in seconds).

    Args:
        None

    Returns:
        float: Video length (in seconds).
    """
    proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                            /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                            string:org.mpris.MediaPlayer2.Player \
                            string:Metadata|egrep -A 1 \"vlc:length\"|cut -b 42-|egrep -v ^$"],
                 shell=True, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    return float(out) / 1000
def get_position(self)

Retrieves the current position in the video being played (in seconds).

Args

None
 

Returns

float
Video position (in seconds).
Expand source code
def get_position(self) -> float:
    """ Retrieves the current position in the video being played (in seconds).

    Args:
        None

    Returns:
        float: Video position (in seconds).
    """
    proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                            /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                            string:org.mpris.MediaPlayer2.Player \
                            string:Position|egrep -A 1 'variant'|cut -b 24-"],
                 shell=True, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    return float(out) / 1000000
def get_rate(self)

Retrieve the rate the current video is being played at.

Args

None
 

Returns

float
Video rate.
Expand source code
def get_rate(self) -> float:
    """ Retrieve the rate the current video is being played at.

    Args:
        None

    Returns:
        float: Video rate.
    """
    proc = Popen(["dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc \
                            /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get \
                            string:org.mpris.MediaPlayer2.Player \
                            string:Rate|egrep -A 1 'variant'|cut -b 25-"],
                 shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    out, err = proc.communicate()

    return float(out)
def next_video(self)

Skips to next video in playlist. Also sets the current loop status to playlist.

Args

None
 

Returns

None
 
Expand source code
def next_video(self):
    """ Skips to next video in playlist.
    Also sets the current loop status to playlist.

    Args:
        None

    Returns:
        None
    """
    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next"], shell=True)
def play_pause_video(self)

Utilize qdbus to play/pause video. If the video is being played, this will pause it. If the video is paused, this will play it.

Args

None
 

Returns

None
 
Expand source code
def play_pause_video(self):
    """ Utilize qdbus to play/pause video.
    If the video is being played, this will pause it. If the video is 
    paused, this will play it.

    Args:
        None

    Returns:
        None
    """
    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause"], shell=True)
def prev_video(self)

Goes back to previous video in playlist. Also sets the current loop status to playlist.

Args

None
 

Returns

None
 
Expand source code
def prev_video(self):
    """ Goes back to previous video in playlist.
    Also sets the current loop status to playlist.

    Args:
        None

    Returns:
        None
    """
    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous"], shell=True)
def randomize_videos(self)

Randomize the order the videos populate the playlist in. Requires: "import random", Requires: "import os"

Args

None
 

Returns

bool
The return value. True for success, False otherwise.
Expand source code
def randomize_videos(self) -> bool:
    """ Randomize the order the videos populate the playlist in.
    Requires: "import random", Requires: "import os"

    Args:
        None

    Returns:
        bool: The return value. True for success, False otherwise.
    """
    # retrieve video file names and store them in a list
    self.entries = os.listdir(self.folder_path)

    # Randomize the list of video files
    random.shuffle(self.entries)
    for entry in self.entries:
        print(entry)

    return True
def reset_rate(self)

Reverts the rate the current video is being played at back to the default speed of 1.0.

Args

None
 

Returns

None
 
Expand source code
def reset_rate(self):
    """ Reverts the rate the current video is being played at back to the default speed of 1.0.

    Args:
        None

    Returns:
        None
    """
    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                string:org.mpris.MediaPlayer2.Player string:Rate variant:double:1.0"], shell=True)
def set_loop_playlist(self)

Set VLC to loop the current playlist if it's currently set to loop the track.

Args

None
 

Returns

None
 
Expand source code
def set_loop_playlist(self):
    """ Set VLC to loop the current playlist if it's currently set to loop the track.

    Args:
        None

    Returns:
        None
    """
    if self.loop_status == "Track":
        self.loop_status = "Playlist"
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)
def set_loop_video(self)

Set VLC to loop the current video if it's currently set to loop the playlist.

Args

None
 

Returns

None
 
Expand source code
def set_loop_video(self):
    """ Set VLC to loop the current video if it's currently set to loop the playlist.

    Args:
        None

    Returns:
        None
    """
    if self.loop_status == "Playlist":
        self.loop_status = "Track"
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)
def set_position(self, track_id, position)

Sets the position of the current video. The track_id must be the the id of the track currently being played.

Args

trackid : str
id of track to be played, gathered from get_id()
position : float
position of video to start playing in microseconds.

Returns

bool
True for success, False for failure
Expand source code
def set_position(self, track_id, position) -> bool:
    """ Sets the position of the current video.
    The track_id must be the the id of the track currently being played.

    Args:
        trackid (str): id of track to be played, gathered from get_id()
        position (float): position of video to start playing in microseconds.

    Returns:
        bool: True for success, False for failure
    """
    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
            /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetPosition objpath:" + track_id + " int64:" + str(position)], shell=True)
    return True
def set_rate(self, rate)

Modifies the playback rate of the video currently being played. This means that as soon as the video ends, the playback rate of VLC will be set back to its default.

Args

rate : double
playback rate.

Returns

None
 
Expand source code
def set_rate(self, rate):
    """ Modifies the playback rate of the video currently being played.
    This means that as soon as the video ends, the playback rate of 
    VLC will be set back to its default.

    Args:
        rate (double): playback rate.

    Returns:
        None
    """
    new_rate = self.get_rate() + rate
    if (new_rate >= RATE_MIN) and (new_rate <= RATE_MAX):
        Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
                    /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
                    string:org.mpris.MediaPlayer2.Player string:Rate variant:double:" + str(new_rate)], shell=True)
def start_vlc(self)

Boots up VLC from shell with various arguments. The various arguments are manipulated within the function itself.

Args

None
 

Returns

bool
True for success, False otherwise.
Expand source code
def start_vlc(self) -> bool:
    """ Boots up VLC from shell with various arguments.
    The various arguments are manipulated within the function itself.

    Args:
        None

    Returns:
        bool: True for success, False otherwise.
    """
    vlc = "vlc"
    dummy_vlc = "cvlc"
    fullscreen = "--fullscreen"
    mute = "--no-audio"
    no_title = "--no-video-title-show"
    anaglyph = "--video-filter=Anaglyph"
    disable_scroll = "--hotkeys-y-wheel-mode=-1"
    disable_mouse = "--no-mouse-events"
    cursor_timeout = "--mouse-hide-timeout=0"
    disable_network = "--no-qt-privacy-ask"
    single_instance = "--one-instance"
    loop = "--loop"
    
    if os.path.exists(self.playlist):
        try:
            # Start VLC process with specified arguments.
            # Args can be in whatever order. Only rule is that "vlc" must be at start, and "self.playlist" must be at end.
            #    Popen([dummy_vlc, anaglyph, fullscreen, mute, no_title, disable_scroll,
            #           disable_mouse, disable_network, cursor_timeout, single_instance, self.playlist])
            # For Testing, disable analglyph to check video playback
            Popen([dummy_vlc, fullscreen, mute, no_title, disable_scroll, loop,
                   disable_mouse, disable_network, cursor_timeout, single_instance, self.playlist])
            return True
        except:
            self.eh.log_critical("VLC could not properly start. Major startup error.")
            raise
    else:
        Popen([dummy_vlc, fullscreen, mute, no_title, disable_scroll, loop,
                   disable_mouse, disable_network, cursor_timeout, single_instance])
        return True
def toggle_loop_video(self)

Toggles between looping the playlist and looping the video currently being played. This loop only occurs if the video hits its end time. It will not occur if we manually skip to the next video.

This option also persists until it's manually changed unlike the video rate option.

Args

None
 

Returns

None
 
Expand source code
def toggle_loop_video(self):
    """ Toggles between looping the playlist and looping the video 
    currently being played. This loop only occurs if the video hits its end 
    time. It will not occur if we manually skip to the next video.

    This option also persists until it's manually changed unlike the 
    video rate option.

    Args:
        None

    Returns:
        None
    """
    if self.loop_status == "Playlist":
        self.loop_status = "Track"
    else:
        self.loop_status = "Playlist"

    Popen(["dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc \
            /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
            string:org.mpris.MediaPlayer2.Player string:LoopStatus variant:string:" + self.loop_status], shell=True)