Vim Tips Wiki
(Insert TipProposed template + manual clean)
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
  +
{{TipProposed
[[File:Placeholder|video|right|300px]] [[File:Placeholder|right|300px]]
 
  +
|id=0
  +
|previous=0
  +
|next=0
  +
|created=August 23, 2013
  +
|complexity=basic
  +
|author=Vimsical
  +
|version=7.0
  +
|subpage=/2013
  +
|category1=
  +
|category2=
  +
}}
 
You can use Vim to control [[wikipedia:VLC media player|VLC]] and edit song lyrics or audio transcripts:
 
*You can add audio timing information to each line of text transcript.
 
*You can cue VLC audio to the time/line you are editing.
   
 
You will need:
You can use vim to control vlc and edit song lyrics or audio transcripts:
 
 
*Vim to edit text.
1. You can add audio timing information to each line of text transcript
 
 
*Perl to connect gvim to vlc via a socket.
2. You can cue vlc audio to the time/line you are editing.
 
  +
*VLC.
   
 
Below: Modify the path to Perl and Vim script according to the directory you save them in.
You will need
 
1. GVIM to edit text
 
2. PERL to connect gvim to vlc via socket,
 
3. VLC
 
   
 
==Setup vlc to listen on a socket==
Below: modify the path to perl and vim script according to the directory
 
you save them in.
 
 
== Setup vlc to listen on a socket ==
 
 
<pre>
 
<pre>
 
" VLC setup: $ vlc > tools > prefs > main interface > enable RC,
 
" VLC setup: $ vlc > tools > prefs > main interface > enable RC,
" Tcp-Input=[localhost:2150] .. ~/vlc/rc.pl will open this socket.
+
" Tcp-Input=[localhost:2150] .. ~/vim/vlc.pl will open this socket.
" Console: [donot_open] console
+
" Console: [donot_open] console
 
</pre>
 
</pre>
  +
== VIM setup ==
+
==Vim setup==
 
<pre>
 
<pre>
 
" VIM Setup:
 
" VIM Setup:
" c:\> vim happy.lrc
+
" c:\> vim c:/atmp/happy.lrc
 
" :so %
 
" :so %
" and cline is '[0:23.10] file:///C:/tmp/happy.mp3'
+
" and cline is '[0:23.10] file:///C:/atmp/happy.mp3' .. press F9 to play from 23s
 
" Music player key:
 
" Music player key:
 
" [F2] Play
 
" [F2] Play
Line 30: Line 40:
 
" [F4] Pause toggle
 
" [F4] Pause toggle
 
" Lyric editor keys:
 
" Lyric editor keys:
" [F9] Set filename or time from cline to vlc.
+
" [F9] Set filename/time from cline to vlc, or get filename/time to cline.
 
" [F10] Get file from vlc into cline.
 
" [F10] Get file from vlc into cline.
" [F11] Get Time from vlc into cline.
+
" [F11] Get Time from vlc into cline.
  +
" Notes:
</nowiki>
 
  +
" To debug: change 'perl ~/vim/vlc.pl' to 'vimrun perl ~/vim/vlc.pl -debug'
== Map your VLC controller keys
 
  +
" Testing:
<nowiki>
 
  +
" Tested gvim73,cygwin perl 5, cygwin,vlc 2, on XP-PRO SP4.
nmap <F2> :silent !perl ~/vlc/rc.pl -cmd=play<CR>
 
  +
" 1. file:///c:/atmp/happy.mp3 .. press F9 play this file in vlc.
nmap <F3> :silent !perl ~/vlc/rc.pl -cmd=stop<CR>
 
  +
" 2. [0:1:4] file:///c:/atmp/happy.mp3 .. press F9 play this file from 64 seconds.
nmap <F4> :silent !perl ~/vlc/rc.pl -cmd=pause<CR>
 
  +
" 3. 0:1:5 .. press F9 to cue/seek vlc to 65 second.
  +
" 4. press F9, to add [time][filename playing in vlc] to this line.
  +
" TODO:
  +
" o Test Audio filenames with spaces, unicode characters
  +
" o Test on Linux
 
" ==============================================================================
  +
 
nmap <F2> :call system("perl ~/vim/vlc.pl -cmd=play")<CR>
 
nmap <F3> :call system("perl ~/vim/vlc.pl -cmd=stop")<CR>
 
nmap <F4> :call system("perl ~/vim/vlc.pl -cmd=pause")<CR>
  +
 
nmap <F9> :call Vlc_Set_File_Time()<CR>
 
nmap <F10> :call Vlc_Get_Filename()<CR>
 
nmap <F11> :call Vlc_Get_Time()<CR>
  +
</pre>
   
  +
==Source vlc.vim==
nmap <F9> :call Mosh_Set_File_Time()<CR>
 
nmap <F10> :call Mosh_Get_Filename()<CR>
 
nmap <F11> :call Mosh_Get_Time()<CR>
 
</pre>
 
== source this file vlc-lrc.vim ==
 
 
<pre>
 
<pre>
  +
" $Header: c:/cvs/repo/mosh/vim/vlc.vim,v 1.1 2013-08-26 17:04:52 a Exp $
  +
" What: VLC remote control, for editing synchronizing lyrics.
  +
" How: Remote control vlc via tcp socket.
 
" AUTHOR: GPL(C) moshahmed/at/gmail
 
" ==============================================================================
 
" ==============================================================================
  +
function! Vlc_Set_File_Time()
" GPL(C) moshahmed
 
function! Mosh_Set_File_Time()
 
" Test [33] file:///c:/tmp/happy.mp3
 
   
 
" Look for filename on cline
 
" Look for filename on cline
 
let l:matcher_file = matchlist(getline('.'),'\v<(file:///.*[.]\w+)>')
 
let l:matcher_file = matchlist(getline('.'),'\v<(file:///.*[.]\w+)>')
  +
let l:absfile = ''
 
if len(l:matcher_file) > 4
 
if len(l:matcher_file) > 4
"echoerr "!perl ~/vlc/rc.pl -cmd=set_file=" . l:matcher_file[1]
+
call system("perl ~/vim/vlc.pl -cmd=set_file=" . l:matcher_file[1])
  +
else
exe ":silent !perl ~/vlc/rc.pl -cmd=set_file=" . l:matcher_file[1]
 
  +
" Look for cfile (filename under cursor) in PWD
  +
let l:cfile = expand("<cfile>")
  +
" let l:absfile = expand("<cfile>:p")
  +
" if len(l:absfile) > 1 && filereadable('"'.l:absfile.'"')
 
" endif
  +
if len(l:cfile) > 4 && filereadable(expand(l:cfile))
  +
let l:absfile = getcwd()."/".l:cfile
  +
if filereadable(l:absfile)
  +
call system("perl ~/vim/vlc.pl -cmd=set_file=file:///".l:absfile)
 
else
  +
echo "Cannot read ".l:absfile
  +
return
  +
endif
  +
endif
 
endif
 
endif
   
Line 61: Line 99:
 
let l:matcher_time = matchlist(getline('.'),'\v\[(\d.*)\]')
 
let l:matcher_time = matchlist(getline('.'),'\v\[(\d.*)\]')
 
if len(l:matcher_time) > 0
 
if len(l:matcher_time) > 0
"echoerr "!perl ~/vlc/rc.pl -cmd=set_time=" . l:matcher_time[1]
+
call system( "perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1])
exe ":silent !perl ~/vlc/rc.pl -cmd=set_time=" . l:matcher_time[1]
 
 
else
 
else
 
" Look for timestamp colon without brackets on cline, eg. 1:2 for 62 seconds.
 
" Look for timestamp colon without brackets on cline, eg. 1:2 for 62 seconds.
 
let l:matcher_time = matchlist(getline('.'),'\v(\d+:[0-9:.]+)')
 
let l:matcher_time = matchlist(getline('.'),'\v(\d+:[0-9:.]+)')
 
if len(l:matcher_time) > 0
 
if len(l:matcher_time) > 0
"echoerr "!perl ~/vlc/rc.pl -cmd=set_time=" . l:matcher_time[1]
+
call system("perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1])
exe ":silent !perl ~/vlc/rc.pl -cmd=set_time=" . l:matcher_time[1]
 
 
endif
 
endif
 
endif
 
endif
   
" If neither file or time on cline, insert them.
+
" If neither filename or time on cline, insert them.
if len(l:matcher_time) < 1 && len(l:matcher_file) < 1
+
if len(l:matcher_time) < 1 && len(l:matcher_file) < 1 && !filereadable(l:absfile)
:call Mosh_Get_Filename()
+
call Vlc_Get_Filename()
:call Mosh_Get_Time()
+
call Vlc_Get_Time()
 
endif
 
endif
 
endfunction
 
endfunction
   
 
" ==============================================================================
 
" ==============================================================================
function! Mosh_Get_Filename()
+
function! Vlc_Get_Filename()
"echoerr "!perl ~/vlc/rc.pl -cmd=get_file"
+
let l:fileis=system("perl ~/vim/vlc.pl -cmd=get_file")
  +
if len(l:fileis) > 0
exe ":r !perl ~/vlc/rc.pl -cmd=get_file"
 
  +
" relfile=$(basename filename), insert shorter relative path if possible.
  +
" TODO: quote filenames; s/// fails if filename has commas, etc.
  +
let l:relfile=substitute(l:fileis, '^.*/', '', '')
  +
if filereadable(l:relfile)
  +
exe ':s,^, '.l:relfile.','
  +
else
  +
exe ':s,^,'.l:fileis.','
  +
endif
  +
endif
 
endfunction
 
endfunction
   
 
" ==============================================================================
 
" ==============================================================================
function! Mosh_Get_Time()
+
function! Vlc_Get_Time()
"echoerr "system perl ~/vlc/rc.pl -cmd=get_time"
+
let l:timeis=system("perl ~/vim/vlc.pl -cmd=get_time")
let l:timeis=system("perl ~/vlc/rc.pl -cmd=get_time")
 
 
if len(l:timeis) > 0
 
if len(l:timeis) > 0
 
let l:timeis=substitute(l:timeis, '[^0-9:.]', '', 'g')
 
let l:timeis=substitute(l:timeis, '[^0-9:.]', '', 'g')
 
let l:timeis='['.l:timeis.']'
 
let l:timeis='['.l:timeis.']'
 
exe ':s/^/'.l:timeis.'/'
 
exe ':s/^/'.l:timeis.'/'
  +
" TODO: try this:
  +
" :put ='"'.l:timeis.'"'
 
endif
 
endif
 
endfunction
 
endfunction
  +
" ==============================================================================
 
" ==============================================================================
 
 
</pre>
 
</pre>
   
  +
==~/vim/vlc.pl==
== Keep this perl file in your path ==
 
 
<pre>
 
<pre>
 
#!/usr/bin/perl -w
 
#!/usr/bin/perl -w
# was telnet.pl from perlmonks, modified to work with vlc remote control.
+
# telnet.pl from perlmonks, modified to work with vlc remote control.
# GPL(C) modifed by moshahmed on 2013-08-22
+
# AUTHOR: GPL(C) moshahmed/at/gmail 2013-08-22
  +
# $Id: vlc.pl,v 1.1 2013-08-26 16:44:44 a Exp $
 
use strict;
 
use strict;
 
use IO::Socket;
 
use IO::Socket;
 
 
my ( $host, $port, $kidpid, $handle, $line );
 
my ( $host, $port, $kidpid, $handle, $line );
 
( $host, $port ) = ('127.0.0.1', 2150);
 
( $host, $port ) = ('127.0.0.1', 2150);
Line 121: Line 166:
 
VLC_CMDS:
 
VLC_CMDS:
 
play, pause, pause (toggle), stop,
 
play, pause, pause (toggle), stop,
get_length .. in seconds
+
get_length .. in h:m:seconds
get_time .. in seconds
+
get_time .. in h:m:seconds
 
get_file .. gets file:///path
 
get_file .. gets file:///path
set_time=1:2:3.40 .. for 1hour 2minutes 3seconds
+
set_time=1:2:3.40 .. for 1hour 2minutes 3seconds (integral seconds only)
 
set_file=file:///c:/tmp/happy.mp3
 
set_file=file:///c:/tmp/happy.mp3
 
};
 
};
Line 135: Line 180:
 
}elsif( m/^-port=(\d+)$/ ){ $port = $1;
 
}elsif( m/^-port=(\d+)$/ ){ $port = $1;
 
}elsif( m/^-cmd=(set_.+)=(.+)$/ ){ $cmd = $1; $value = $2;
 
}elsif( m/^-cmd=(set_.+)=(.+)$/ ){ $cmd = $1; $value = $2;
 
$value = hms_to_seconds($value);
# convert: 1:2:3.4 => 1h.2m.3.4s into seconds.
 
if ($cmd eq 'set_time' && $value =~ m,:, ) {
+
warn "$cmd=$value\n" if $debug;
my ($timeis,$factor)=(0,1);
 
while( $value =~ s,^(\d+):,, ) {
 
$factor *= 60;
 
$timeis += $factor * $1;
 
}
 
$timeis += $value;
 
$value = int($timeis);
 
}
 
die "debug: -cmd=$cmd=$value\n" if $debug;
 
 
}elsif( m/^-cmd=(.+)$/ ){ $cmd = $1;
 
}elsif( m/^-cmd=(.+)$/ ){ $cmd = $1;
}elsif( m/^-linein$/ ){ $linein=1;
+
}elsif( m/^-linein$/ ){ $linein=1; # read stdin (unused).
 
}else{ die $USAGE,"Unknown option '$_'\n"; }
 
}else{ die $USAGE,"Unknown option '$_'\n"; }
 
}
 
}
  +
  +
# foreach(@ARGV) { } .. process leftover args (unused).
   
 
# create a tcp connection to the specified host and port
 
# create a tcp connection to the specified host and port
Line 165: Line 203:
 
DONE:
 
DONE:
 
while ( defined( $line = <$handle> ) ) {
 
while ( defined( $line = <$handle> ) ) {
if ($cmd eq 'get_length') {
+
if ($cmd eq 'get_length') {
 
if( $line =~ m,^\d+,) {
 
if( $line =~ m,^\d+,) {
print STDOUT $line;
+
print STDOUT seconds_to_hms($line);
 
last DONE;
 
last DONE;
 
}
 
}
 
}elsif($cmd eq 'get_time') {
 
}elsif($cmd eq 'get_time') {
 
if( $line =~ m,^\d+,) {
 
if( $line =~ m,^\d+,) {
print STDOUT $line;
+
print STDOUT seconds_to_hms($line);
 
last DONE;
 
last DONE;
 
}
 
}
Line 207: Line 245:
 
}
 
}
 
exit 0;
 
exit 0;
}
+
}
  +
  +
sub seconds_to_hms {
  +
my $hourz=int($_[0]/3600);
  +
my $leftover=$_[0] % 3600;
  +
my $minz=int($leftover/60);
  +
my $secz=int($leftover % 60);
  +
if ($hourz > 0){
  +
return sprintf ("%d:%02d:02%d", $hourz,$minz,$secz)
  +
}
  +
# print 3 seconds as 00:03, so timestamp always has a colon.
  +
return sprintf ("%02d:%02d", $minz,$secz)
  +
}
  +
  +
sub hms_to_seconds {
 
# hms_to_seconds(1:2:3.4) => 1h.2m.3.4s = 1*3600+2*60+3 = 3723.
 
my $hms = $_[0];
  +
if ( $hms =~ m,^(\d+):(\d+):(\d+), ) { # ignore trailing chars.
  +
return $1 * 3600 + $2 * 60 + $3;
 
}elsif( $hms =~ m,^(\d+):(\d+), ) {
 
return $1 * 60 + $2;
  +
}
  +
return $hms;
  +
}
 
</pre>
 
</pre>
  +
  +
==Comments==
  +
That's a lot of script for a tip. I have done some quick formatting, but have not thought about the proposed tip yet. One point is that the "Mosh" function names are a bit jarring and should be replaced with <code>s:</code>. [[User:JohnBeckett|JohnBeckett]] ([[User talk:JohnBeckett|talk]]) 05:16, August 24, 2013 (UTC)

Latest revision as of 10:40, 31 January 2014

Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).

Please use new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
created August 23, 2013 · complexity basic · author Vimsical · version 7.0

You can use Vim to control VLC and edit song lyrics or audio transcripts:

  • You can add audio timing information to each line of text transcript.
  • You can cue VLC audio to the time/line you are editing.

You will need:

  • Vim to edit text.
  • Perl to connect gvim to vlc via a socket.
  • VLC.

Below: Modify the path to Perl and Vim script according to the directory you save them in.

Setup vlc to listen on a socket[]

"   VLC setup: $ vlc > tools > prefs > main interface > enable RC,
"       Tcp-Input=[localhost:2150]  .. ~/vim/vlc.pl will open this socket.
"       Console: [donot_open] console

Vim setup[]

"   VIM Setup:
"     c:\> vim c:/atmp/happy.lrc
"     :so %
"     and cline is '[0:23.10] file:///C:/atmp/happy.mp3' .. press F9 to play from 23s
"   Music player key:
"     [F2] Play
"     [F3] Stop
"     [F4] Pause toggle
"   Lyric editor keys:
"     [F9]  Set filename/time from cline to vlc, or get filename/time to cline.
"     [F10] Get file from vlc into cline.
"     [F11] Get Time from vlc into cline.
" Notes:
"     To debug: change 'perl ~/vim/vlc.pl' to 'vimrun perl ~/vim/vlc.pl -debug'
" Testing:
"     Tested gvim73,cygwin perl 5, cygwin,vlc 2, on XP-PRO SP4.
"     1. file:///c:/atmp/happy.mp3 .. press F9 play this file in vlc.
"     2. [0:1:4] file:///c:/atmp/happy.mp3 .. press F9 play this file from 64 seconds.
"     3. 0:1:5 .. press F9 to cue/seek vlc to 65 second.
"     4. press F9, to add [time][filename playing in vlc] to this line.
" TODO:
"     o Test Audio filenames with spaces, unicode characters
"     o Test on Linux
" ==============================================================================

nmap <F2>   :call system("perl ~/vim/vlc.pl -cmd=play")<CR>
nmap <F3>   :call system("perl ~/vim/vlc.pl -cmd=stop")<CR>
nmap <F4>   :call system("perl ~/vim/vlc.pl -cmd=pause")<CR>

nmap <F9>   :call Vlc_Set_File_Time()<CR>
nmap <F10>  :call Vlc_Get_Filename()<CR>
nmap <F11>  :call Vlc_Get_Time()<CR>

Source vlc.vim[]

" $Header: c:/cvs/repo/mosh/vim/vlc.vim,v 1.1 2013-08-26 17:04:52 a Exp $
" What: VLC remote control, for editing synchronizing lyrics.
" How:  Remote control vlc via tcp socket.
" AUTHOR: GPL(C) moshahmed/at/gmail
" ==============================================================================
function! Vlc_Set_File_Time()

  " Look for filename on cline
  let l:matcher_file = matchlist(getline('.'),'\v<(file:///.*[.]\w+)>')
  let l:absfile = ''
  if len(l:matcher_file) > 4
    call system("perl ~/vim/vlc.pl -cmd=set_file=" . l:matcher_file[1])
  else
    " Look for cfile (filename under cursor) in PWD
    let l:cfile = expand("<cfile>")
    " let l:absfile = expand("<cfile>:p")
    " if len(l:absfile) > 1 && filereadable('"'.l:absfile.'"')
    " endif
    if len(l:cfile) > 4 && filereadable(expand(l:cfile))
      let l:absfile = getcwd()."/".l:cfile
      if filereadable(l:absfile)
        call system("perl ~/vim/vlc.pl -cmd=set_file=file:///".l:absfile)
      else
        echo "Cannot read ".l:absfile
        return
      endif
    endif
  endif

  " Look for timestamp on cline, eg. [10] for 10 seconds, [1:1] for 61 seconds.
  let l:matcher_time = matchlist(getline('.'),'\v\[(\d.*)\]')
  if len(l:matcher_time) > 0
    call system( "perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1])
  else
    " Look for timestamp colon without brackets on cline, eg. 1:2 for 62 seconds.
    let l:matcher_time = matchlist(getline('.'),'\v(\d+:[0-9:.]+)')
    if len(l:matcher_time) > 0
      call system("perl ~/vim/vlc.pl -cmd=set_time=" . l:matcher_time[1])
    endif
  endif

  " If neither filename or time on cline, insert them.
  if len(l:matcher_time) < 1 && len(l:matcher_file) < 1 && !filereadable(l:absfile)
    call Vlc_Get_Filename()
    call Vlc_Get_Time()
  endif
endfunction

" ==============================================================================
function! Vlc_Get_Filename()
  let l:fileis=system("perl ~/vim/vlc.pl -cmd=get_file")
  if  len(l:fileis) > 0
    " relfile=$(basename filename), insert shorter relative path if possible.
    " TODO: quote filenames; s/// fails if filename has commas, etc.
    let l:relfile=substitute(l:fileis, '^.*/', '', '')
    if filereadable(l:relfile)
      exe ':s,^, '.l:relfile.','
    else
      exe ':s,^,'.l:fileis.','
    endif
  endif
endfunction

" ==============================================================================
function! Vlc_Get_Time()
  let l:timeis=system("perl ~/vim/vlc.pl -cmd=get_time")
  if  len(l:timeis) > 0
    let l:timeis=substitute(l:timeis, '[^0-9:.]', '', 'g')
    let l:timeis='['.l:timeis.']'
    exe ':s/^/'.l:timeis.'/'
    " TODO: try this:
    " :put ='"'.l:timeis.'"'
  endif
endfunction
" ==============================================================================

~/vim/vlc.pl[]

#!/usr/bin/perl -w
# telnet.pl from perlmonks, modified to work with vlc remote control.
# AUTHOR: GPL(C) moshahmed/at/gmail 2013-08-22
# $Id: vlc.pl,v 1.1 2013-08-26 16:44:44 a Exp $
use strict;
use IO::Socket;
my ( $host, $port, $kidpid, $handle, $line );
( $host, $port ) = ('127.0.0.1', 2150);
my ($verbose,$debug,$cmd,$value,$linein) = (0,0,'',,'');

my $USAGE=q{
USAGE: $0 [options] -cmd=VLC_CMDS
WHAT: control vlc from vim
Options:
    -port=NN  .. default ($port)
    -h      .. help.
    -v      .. verbose
    -debug  .. to debug, also use ./telnet.pl to communicate with vlc
VLC_CMDS:
    play, pause, pause (toggle), stop,
    get_length .. in h:m:seconds
    get_time   .. in h:m:seconds
    get_file   .. gets file:///path
    set_time=1:2:3.40  .. for 1hour 2minutes 3seconds (integral seconds only)
    set_file=file:///c:/tmp/happy.mp3
};

# Process args
while( $_ = $ARGV[0], defined($_) && m/^-/ ){ shift; last if /^--$/; if(0){
    }elsif( m/^-[h?]$/ ){ die $USAGE;
    }elsif( m/^-v$/    ){ $verbose++;
    }elsif( m/^-debug$/    ){ $debug++;
    }elsif( m/^-port=(\d+)$/ ){ $port = $1;
    }elsif( m/^-cmd=(set_.+)=(.+)$/ ){ $cmd = $1; $value = $2;
      $value = hms_to_seconds($value);
      warn "$cmd=$value\n" if $debug;
    }elsif( m/^-cmd=(.+)$/ ){ $cmd = $1;
    }elsif( m/^-linein$/ ){ $linein=1; # read stdin (unused).
    }else{ die $USAGE,"Unknown option '$_'\n"; }
}

# foreach(@ARGV) { } .. process leftover args (unused).

# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(
    Proto    => "tcp", PeerAddr => $host, PeerPort => $port
  ) or die "can't connect to port $port on $host: $!";
  $handle->autoflush(1);    # so output gets there right away
print STDERR "[Connected to $host:$port]\n" if $verbose;

# split the program into two processes, identical twins
die "can't fork: $!" unless defined( $kidpid = fork() );

if ($kidpid) { # In parent, parse reply from vlc.
    # the if{} part runs only in the parent process
    DONE:
    while ( defined( $line = <$handle> ) ) {
      if    ($cmd eq 'get_length') {
        if( $line =~ m,^\d+,) {
          print STDOUT seconds_to_hms($line);
          last DONE;
        }
      }elsif($cmd eq 'get_time') {
        if( $line =~ m,^\d+,) {
          print STDOUT seconds_to_hms($line);
          last DONE;
        }
      }elsif($cmd eq 'get_file') {
        if( $line =~ m,(file://.*)\s[()],i ) {
          my $filename = $1;
          print STDOUT $filename;
          last DONE;
        }
      }elsif($cmd eq 'status') {
        print STDOUT $line;
        last DONE if $line =~ m,returned,;
      }elsif($cmd eq 'play') { last DONE;
      }elsif($cmd eq 'pause') { last DONE;
      }elsif($cmd eq 'stop') { last DONE;
      }else{ print STDOUT $line;
        last DONE if $line =~ m,returned,;
      }
    } # DONE
    kill( "TERM", $kidpid );    # send SIGTERM to child
    exit 0;
} else {  # In child? send cmd to vlc
    if(     $cmd eq 'status' ){ print $handle "$cmd\n";
    }elsif( $cmd eq 'play' ){ print $handle "$cmd\n";
    }elsif( $cmd eq 'pause' ){ print $handle "$cmd\n";
    }elsif( $cmd eq 'stop' ){ print $handle "$cmd\n";
    }elsif( $cmd eq 'get_time' ){ print $handle "$cmd\n";
    }elsif( $cmd eq 'get_file' ){ print $handle
        "pause\nstatus\npause\nstatus\n";
    }elsif( $cmd eq 'get_length' ){ print $handle "play\nget_length\n";
    }elsif( $cmd eq 'set_time' ){ print $handle "seek $value\n";
    }elsif( $cmd eq 'set_file' ){ print $handle "clear\nadd $value\n";
    }else{                        print $handle "$cmd\n";
    }
    exit 0;
}

sub seconds_to_hms {
  my $hourz=int($_[0]/3600);
  my $leftover=$_[0] % 3600;
  my $minz=int($leftover/60);
  my $secz=int($leftover % 60);
  if ($hourz > 0){
    return sprintf ("%d:%02d:02%d", $hourz,$minz,$secz)
  }
  # print 3 seconds as 00:03, so timestamp always has a colon.
  return sprintf ("%02d:%02d", $minz,$secz)
}

sub hms_to_seconds {
    # hms_to_seconds(1:2:3.4) => 1h.2m.3.4s = 1*3600+2*60+3 = 3723.
    my $hms = $_[0];
    if ( $hms =~ m,^(\d+):(\d+):(\d+), ) { # ignore trailing chars.
      return $1 * 3600 + $2 * 60 + $3;
    }elsif( $hms =~ m,^(\d+):(\d+), ) {
      return $1 * 60 + $2;
    }
    return $hms;
}

Comments[]

That's a lot of script for a tip. I have done some quick formatting, but have not thought about the proposed tip yet. One point is that the "Mosh" function names are a bit jarring and should be replaced with s:. JohnBeckett (talk) 05:16, August 24, 2013 (UTC)