Updated 2018-01-23 04:55:28 by DDG

Widget wrapper for the mplayer media application edit

An easy wrapper for the famous mplayer to embed videos into Tcl/Tk applications.

Links

Provide
#!/usr/bin/tclsh
# Author: Detlef Groth
# License MIT 
# Version 0.2 working and usable
# Version 0.2 adds support for direct play of youtube videos
# Version 0.3 fixes issue if youtube-dl is not installed but tried to load an youtube video
# youtube-dl script is required for youtube urls see https://rg3.github.io/youtube-dl/

package require Tk
package require snit
package provide SnitMPlayer 0.3

snit::widget SnitMPlayer {
    option -infile ""
    variable mplayer ""
    variable position 0:00
    constructor {args} {
        $self configurelist $args
        frame $win.f -container yes
        pack $win.f -fill both -expand yes
        set toolbar [frame $win.toolbar]
        pack [button $win.toolbar.btnopen -command [mymethod fileOpen] -image fileopen-16] -side left -padx 5 -pady 5
        pack [button $win.toolbar.btnpaase -command [mymethod mplayerCmd] -image playpause16] -side left -padx 5 -pady 5
        pack [button $win.toolbar.btnstart -command [mymethod mplayerCmd "set_property time_pos 0"] -image player_start-16] -side left -padx 5 -pady 5
        pack [button $win.toolbar.btnforward -command [mymethod mplayerCmd "seek -10"] -image 1leftarrow-16] -side left -padx 5 -pady 5
        pack [button $win.toolbar.btnbackward -command [mymethod mplayerCmd "seek +10"] -image 1rightarrow-16] -side left -padx 5 -pady 5
        pack [button $win.toolbar.btnend -command [mymethod mplayerCmd "seek 99.5 1"] -image player_end-16] -side left -padx 5 -pady 5

        pack [button $win.toolbar.btnaudiodn -command [mymethod mplayerCmd "volume -10"] -image actitemdelete16] -side left -padx 5 -pady 5

        pack [button $win.toolbar.btnaudioup -command [mymethod mplayerCmd "volume +10"] -image actitemadd16] -side left -padx 5 -pady 5
        pack [entry $win.toolbar.pos -textvariable [myvar position] -width 6] -side left -padx 5 -pady 5
        bind $win.toolbar.pos <Return> [mymethod gotoPosition]
        pack [button $win.toolbar.btnexit -command [mymethod exit] -image actcross16] -side left -padx 5 -pady 5
    }
    typeconstructor {
        image create photo 1leftarrow-16 -data {
            R0lGODlhEAAQAIAAAP///wAAACH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxqd
            woNGTmgvy9px/IEWBWRkKZ2oWrKu4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJ
            RiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwg
            cmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==
        }
        image create photo 1rightarrow-16 -data {
            R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxCt
            woNHTmpvy3rxnnwQh1mUI52o6rCu6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJ
            RiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwg
            cmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==
        }
        image create photo player_start-16 -data {
            R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pyxud
            wlNyguqkqRZh3h0gl43hpoElqlHt9UKw7NG27BcAIf5oQ3JlYXRlZCBieSBC
            TVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4
            LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5j
            b20AOw==
        }
        image create photo player_end-16 -data {
            R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+py8Eb
            3ENRggrxjRnrVIWcIoYd91FaenysMU6wTNeLXwAAIf5oQ3JlYXRlZCBieSBC
            TVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4
            LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5j
            b20AOw==
        }

        image create photo player_stop-16 -data {
            R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+1v
            gpySUWpvXXqrHmSaeJEYhKYq6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQ
            cm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmln
            aHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==
        }
        image create photo fileopen-16 -data {
            R0lGODlhEAAQAIUAAPwCBAQCBOSmZPzSnPzChPzGhPyuZEwyHExOTFROTFxa
            VFRSTMSGTPT29Ozu7Nze3NTS1MzKzMTGxLy6vLS2tLSytDQyNOTm5OTi5Ly+
            vKyqrKSmpIyOjLR+RNTW1MzOzJyenGxqZBweHKSinJSWlExKTMTCxKyurGxu
            bBQSFAwKDJyanERCRERGRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaR
            QIBwGCgGhkhkEWA8HpNPojFJFU6ryitTiw0IBgRBkxsYFAiGtDodDZwPCERC
            EV8sEk0CI9FoOB4BEBESExQVFgEEBw8PFxcYEBIZGhscCEwdCxAPGA8eHxkU
            GyAhIkwHEREQqxEZExUjJCVWCBAZJhEmGRUnoygpQioZGxsnxsQrHByzQiJx
            z3EsLSwWpkJ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9u
            IDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2
            ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
        }
        image create photo playpause16 -data {
            R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+py+1v
            goxzyUCxrZd18ClfmIyVyJ1lqkHuC0N+AQAh/mhDcmVhdGVkIGJ5IEJNUFRv
            R0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFs
            bCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
        }
        image create photo actitemadd16 -data {
            R0lGODlhEAAQAIQAAPwCBERCBKSepJyenJyWnJyanJSWlJSOlJSSlIyKjIyG
            jISGhIR+hGRiZHx+fHx2fERGBHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
            AAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVpICCOZGkG
            aGqSgTAMRLCOQTEY8SzWBHHIpRTKgED8hDtBoWBoHhKKxYIRaABqBYTh8Iwy
            HI/qtdA7GBQJKYPxgFgDRKPC64hEwm9heuEQillTdVUNhFYsEQ5sfysBYA94
            On6LK4WFJH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24g
            Mi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZl
            ZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=
        }
        image create photo actitemdelete16 -data {
            R0lGODlhEAAQAIMAAPwCBERCBKSmpGRiZJSWlJyanIyKjIR+hHx6fAAAAAAA
            AAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ4EMhJq704681n
            +GAYSoFgnqgZDEBAFEbxxnOxtoeh77xxB4jgIYgYEn+i5IcFGDifUGhnSq1a
            /BEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkg
            RGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0
            cDovL3d3dy5kZXZlbGNvci5jb20AOw==
        }
        image create photo actcross16 -data {
            R0lGODlhEAAQAIIAAASC/PwCBMQCBEQCBIQCBAAAAAAAAAAAACH5BAEAAAAA
            LAAAAAAQABAAAAMuCLrc/hCGFyYLQjQsquLDQ2ScEEJjZkYfyQKlJa2j7AQn
            MM7NfucLze1FLD78CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJz
            aW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVz
            ZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
        }



    }
    destructor {
        if {$mplayer ne ""} {
            puts $mplayer "quit"
            flush $mplayer
        }
    }
    method addToolbar {} {
        pack $win.toolbar -side top -expand false -anchor c
    }
    method ReadPipe {chan} {
        set d [read $chan]
        foreach line [split $d \n] {
            set line [string trim $line]
            puts $line
        }
        if {[eof $chan]} {
            fileevent $chan readable {}
            close $chan
            set mplayer ""
        }
    }
    method openVideo {filename} {
        if {[regexp {https://www.youtube} $filename]} {
            if {[auto_execok youtube-dl] eq ""} {
                tk_messageBox -title "Error!" -icon error -message "This feature requires youtube-dl commandline application" -type ok
                # dummy pipe for local files starting
                # just start an idle pipe waiting for local file input
                set fid [open "|mplayer -vo xv -zoom -slave -idle -fstype fullscreen -wid [winfo id $win.f]" r+]
                #puts "fid=$fid"
            } else {
                set url [exec youtube-dl -g -f 22 --cookies /tmp/cookie.txt $filename]
                # need to remove -quiet
                set fid [open "|mplayer -vo xv -zoom -slave -idle -fstype fullscreen -wid [winfo id $win.f] -fs -cookies -cookies-file /tmp/cookie.txt $url" r+]
            }
        } else {
            set fid [open "|mplayer -vo xv -zoom -slave -ss 0:00 -quiet -idle -fstype fullscreen -wid [winfo id $win.f] $filename" r+]
            
        }
        fconfigure $fid -blocking 0 -buffering line
        fileevent $fid readable [mymethod ReadPipe $fid]
        set mplayer $fid
    }
    method fileOpen {} {
        set types {
            {{Video Files}       {.avi .mp4}        }
            {{Audio Files}       {.mp3 .ogg}        }
            {{All Files}        *             }
        }
        set filename [tk_getOpenFile -filetypes $types]
        if {$filename != ""} {
            $self mplayerCmd stop
            after 500        
            # Open the file ...
            $self mplayerCmd "loadfile $filename"
        }
    }
    method mplayerCmd {{arg pause}} {
        puts $mplayer $arg
        flush $mplayer
    }
    method gotoPosition {} {
        set pos [split $position ":"]
        set seconds [expr {[lindex $pos 0]*60+[lindex $pos 1]}]
        $self mplayerCmd "seek $seconds 2"
    }
    method exit {} {
        $self mplayerCmd "stop"
        #rename $win ""
    }

}

if {$argv0 eq [info script]} {
    SnitMPlayer .smp
    pack .smp -fill both -expand yes
    .smp addToolbar
    puts [llength $argv]
    if {[llength $argv] == 1} {
        .smp openVideo [lindex $argv 0]
    } else {
        .smp openVideo https://www.youtube.com/watch?v=ATUyKlQpC4k
    }
}

# $ tclsh SnitMPlayer.tcl https://www.youtube.com/watch?v=zE_3ZYi6iTU