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