1 Introduction
2 Processes & Connections
vlc?
current-vlc
connect-to-vlc
start-vlc
3 URLs
vlc-url?
to-vlc-rc-url-bytes
4 Commands
4.1 Playlist
vlc-clear
vlc-add
vlc-enqueue
vlc-next
vlc-prev
4.2 Repeat / Loop / Random
vlc-repeat
vlc-loop
vlc-random
4.3 Title and Chapter
vlc-title-n
vlc-title-p
vlc-chapter-n
vlc-chapter-p
4.4 Play, Pause, and Stop
vlc-play
vlc-pause
vlc-stop
vlc-is-playing
4.5 Rate
vlc-fastforward
vlc-rewind
vlc-faster
vlc-slower
vlc-normal
vlc-frame
vlc-rate
4.6 Absolute Position
vlc-get-time
vlc-get-length
vlc-seek
4.7 Audio, Video, and Subtitle Tracks
vlc-atrack
vlc-vtrack
vlc-strack
4.8 Audio Options
4.9 Video Options
vlc-fullscreen
4.10 Misc. Info
vlc-get-title
vlc-status
5 Snapshots
vlc-snapshot
6 Exiting
vlc-shutdown
7 Other Operations
wait-for-vlc-active-playing
8 Known Issues
9 History
10 Legal
Version: 1:2

vlc: VideoLAN VLC Media Player Control in Racket

Neil Van Dyke

 (require (planet neil/vlc:1:2))

1 Introduction

This vlc package permit Racket programs to start and control a VideoLAN VLC media player, for playing video and audio.
VLC itself is a separate computer program, and must be installed separately.
This package uses the VLC RC interface over TCP. The Racket host OS process’s address space is isolated from potential memory-handling defects in the various native code libraries involved in media playing.
For a simple example of using this package, imagine that you are studying how to improve a corporate training video, and you have a theory that the video would be more efficacious, were minimum-wage new hires not bored to catatonia by the CEO’s rambling 10-minute introduction. Fortunately, you have human subjects available, since the new hires all use a Racket-based training system that can be modified quickly to add scientific experiments, showing the CEO’s intro to some subjects but not to others. Unfortunately, you can’t just edit the training video to make an alternate version without the CEO’s intro, since the CEO is an aspiring Hollywood actor, who negotiated “points” on DVD sales. Fortunately, you can use VLC and this Racket vlc package, to launch the pertinent DVD chapter and seek past the initial 10 minutes of Valium:
(start-vlc "dvd:///dev/dvd#1:2")
(wait-for-vlc-active-playing)
(vlc-seek 594)
In addition to highly contrived examples like that, this package is being used as part of a Racket-based home theatre system being developed.
This package is currently developed using VLC 2.0.3, on Debian GNU/Linux, and has been observed to also work on Mac OS X. MS Windows is not currently supported (since, on MS Windows, VLC 2.0.3 does not support the RC interface, and instead uses something called oldrc).

2 Processes & Connections

A connection to a VLC process is represented by the vlc object. This connection can be to a process that is started by the start-vlc procedure, or an existing VLC process (possibly on a host elsewhere on the network).

procedure

(vlc? x)  boolean?

  x : any/c
Predicate for whether or not x is a vlc object.

parameter

(current-vlc)  (or/c vlc? #f)

(current-vlc vlc)  void?
  vlc : (or/c vlc? #f)
Parameter for the vlc to use as the default for most procedures in this package when the optional #:vlc argument is not supplied to the procedure.

procedure

(connect-to-vlc #:port port    
  [#:hostname hostname    
  #:connecting-timeout connecting-timeout    
  #:set-current-vlc? set-current-vlc?])  vlc?
  port : 
(and/c exact-nonnegative-integer?
       (integer-in 1 65535))
  hostname : string? = "localhost"
  connecting-timeout : (and/c real? (not/c negative?)) = 5.0
  set-current-vlc? : boolean? = #t
Connect to the RC interface on an existing process, at TCP hostname and port, and return a vlc object. If set-current-vlc? is true, which is the default, then the current-vlc parameter is also set.
connecting-timeout is a guideline of the maximum number of seconds total that should be spend attempting to get a TCP connection to the VLC process and then exchange certain initial protocol. It is not a hard limit, however. Note that multiple attempts at the TCP connection may be tried within that limit, for situations such as waiting for a VLC process to start up.

procedure

(start-vlc [#:port port    
  #:hostname hostname    
  #:connecting-timeout connecting-timeout    
  #:logger logger    
  #:logger-level logger-level    
  #:set-current-vlc? set-current-vlc?    
  #:command command    
  extra-args ...])  vlc?
  port : 
(or/c #f
      (and/c exact-nonnegative-integer?
             (integer-in 1 65535)))
 = #f
  hostname : string? = "localhost"
  connecting-timeout : (or/c #f (and/c real? (not/c negative?)))
   = 60.0
  logger : (or/c #f logger?) = (current-logger)
  logger-level : (or/c 'fatal 'error 'warning 'info 'debug)
   = 'info
  set-current-vlc? : boolean? = #t
  command : (or/c #f path-string?) = #f
  extra-args : (listof (or/c string? path?)) = '()
Start a VLC process on the same machine on which this Racket program is running, with RC enabled, and connect to it. A vlc object is returned. If set-current-vlc? is true, which is the default, then the current-vlc parameter is also set.
command is a string or path object for the complete path to the VLC executable; or, if the default of #f, then this package attempts to find the VLC executable.
This package supplies some command-line arguments to VLC, to set up the RC interface. Additional command-line arguments can be supplied as strings and/or path objects to the extra-args argument of this procedure.
(start-vlc "--snapshot-path=/home/me/film-class/review-screenshots"
           "dvd:///dev/dvd")
If logger is #f, then stdout and stderr output is consumed and ignored. Otherwise, such output is redirected to the logger, with the log level specified by logger-level.
If port is #f, which is the default, then this package attempts to select a TCP port in the ephemeral range for VLC to use for RC; otherwise, port is the port number to use.
hostname is the string hostname (or the IP address as a string) on which VLC should listen on the TCP port for RC. By default, this is "localhost", which is what you normally want with start-vlc rather than connect-to-vlc. In the unlikely event that you wish for the RC port of this VLC process to also be accessible from other hosts, you may supply the hostname or IP address for a non-localhost interface.
connecting-timeout is as documented for connect-to-vlc.
The VLC process is started under the current custodian. If you are calling start-vlc from a short-lived thread with its own custodian that you shutdown as the thread exits, such as for an HTTP request that triggers starting of VLC, you might want to do something like:
(parameterize ((current-custodian <long-lived-custodian>))
  (start-vlc))

3 URLs

URLs may be provided to VLC commands in any of a few different formats. See documentation for vlc-url?.

procedure

(vlc-url? x)  boolean?

  x : any/c
Predicate for whether or not x can (likely) be used as a URL argument to procedures like vlc-add and vlc-enqueue. Specifically, URLs can be represented as one of the following:
  • String starting with a URL scheme, such as "http://example.com/foo.mp4". Note that this string must contain a %-escaped URL, with no spaces or other problematic characters.

  • url object, such as is produced by (string->url "http://example.com/bar/foo.mp4").

  • String not starting with a URL scheme, such as "/home/billybob/tractors.mp4", which is a file path.

  • path object, such as is produced by (string->path "/home/scotty/sheep.wav").

  • Byte string of a complete URL in UTF-8 encoding, including %-escaping. This is passed verbatim in the RC protocol.

Note that URLs provided to commands are processed by the VLC program, which might be on a different computer than the Racket program that is sending commands. URLs that may be accessed from one computer can’t necessarily be accessed by another.

procedure

(to-vlc-rc-url-bytes x)  bytes?

  x : (or/c string? path? url? bytes?)
Accepts a VLC URL as described in the documentation for vlc-url? and yields a byte string representation. Note that, if x is a byte string, then it is returned verbatim. This procedure will not be called directly by most programs using this package.

4 Commands

This section lists the various command procedures. Generally, each procedure corresponds to a VLC RC command. For example, vlc-add corresponds to the RC add command. For the most part, these procedures are defined to “do whatever the RC command does.” The RC command itself might not be well-documented. So, for example, if, in the version of VLC being used, the add command results in the the specified URL both being prepended to the playlist and being played, then that’s what the vlc-add command will do.
Note that some of these commands have asynchronous effects, due to the design of VLC or of the VLC RC protocol. For example, the vlc-play procedure can return before VLC is actually playing the media.

4.1 Playlist

procedure

(vlc-clear [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Clear all items from the playlist.

procedure

(vlc-add thing [#:vlc vlc])  void?

  thing : vlc-url?
  vlc : vlc? = (current-vlc)
Adds the URL thing to the playlist. This command seems to also cause VLC to start playing the item.

procedure

(vlc-enqueue thing [#:vlc vlc])  void?

  thing : vlc-url?
  vlc : vlc? = (current-vlc)
Enqueues the URL thing in the playlist.

procedure

(vlc-next [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Start playing the next item in the playlist.

procedure

(vlc-prev [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Start playing the previous item in the playlist.

4.2 Repeat / Loop / Random

procedure

(vlc-repeat on? [#:vlc vlc])  void?

  on? : boolean
  vlc : vlc? = (current-vlc)
Set whether VLC should repeat playing the current stream continuously.

procedure

(vlc-loop on? [#:vlc vlc])  void?

  on? : boolean
  vlc : vlc? = (current-vlc)
Set whether VLC should repeat playing the playlist continuously.

procedure

(vlc-random on? [#:vlc vlc])  void?

  on? : boolean
  vlc : vlc? = (current-vlc)
Set whether VLC should select streams from the playlist randomly, rather than in order.

4.3 Title and Chapter

procedure

(vlc-title-n [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Switch to the next title of the current stream.

procedure

(vlc-title-p [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Switch to the previous title of the current stream.

procedure

(vlc-chapter-n [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Switch to the next chapter of the current stream.

procedure

(vlc-chapter-p [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Switch to the previous chapter of the current stream.

4.4 Play, Pause, and Stop

procedure

(vlc-play [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Play the next stream, if not already playing one.

procedure

(vlc-pause [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Toggle the playing pause state.

procedure

(vlc-stop [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Stop playing the current stream, if playing or paused.

procedure

(vlc-is-playing [#:vlc vlc])  number?

  vlc : vlc? = (current-vlc)
Yields a boolean value for whether or not a stream is playing.

4.5 Rate

procedure

(vlc-fastforward [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Set rate of playing to maximum.

procedure

(vlc-rewind [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Set rate of playing to maximum reverse.

procedure

(vlc-faster [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Increase the rate of playing of the current stream.

procedure

(vlc-slower [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Lower the rate of playing of the current stream.

procedure

(vlc-normal [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Play the current stream, and at normal speed.

procedure

(vlc-frame [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Set current stream playing to frame-by-frame, or advance one frame.

procedure

(vlc-rate rate [#:vlc vlc])  void?

  rate : real?
  vlc : vlc? = (current-vlc)
Set playing rate to rate.

4.6 Absolute Position

procedure

(vlc-get-time [#:vlc vlc])  number?

  vlc : vlc? = (current-vlc)
Get the time position of the current stream, in seconds.

procedure

(vlc-get-length [#:vlc vlc])  number?

  vlc : vlc? = (current-vlc)
Get the length of the current stream, in seconds.

procedure

(vlc-seek seconds [#:vlc vlc])  void?

  seconds : exact-nonnegative-integer?
  vlc : vlc? = (current-vlc)
Seek playing to position seconds.

4.7 Audio, Video, and Subtitle Tracks

procedure

(vlc-atrack [#:vlc vlc])

  
integer?
(listof (cons/c string? (listof (cons/c string? integer?))))
  vlc : vlc? = (current-vlc)
(vlc-atrack num [#:vlc vlc])  void?
  num : integer?
  vlc : vlc? = (current-vlc)
If num is not provided, yields information about current and available audio tracks for the current stream.
If num is provided, switches the audio to that track.

procedure

(vlc-vtrack [#:vlc vlc])

  
integer?
(listof (cons/c string? (listof (cons/c string? integer?))))
  vlc : vlc? = (current-vlc)
(vlc-vtrack num [#:vlc vlc])  void?
  num : integer?
  vlc : vlc? = (current-vlc)
If num is not provided, yields information about current and available video tracks for the current stream.
If num is provided, switches the audio to that track.

procedure

(vlc-strack [#:vlc vlc])

  
integer?
(listof (cons/c string? (listof (cons/c string? integer?))))
  vlc : vlc? = (current-vlc)
(vlc-strack num [#:vlc vlc])  void?
  num : integer?
  vlc : vlc? = (current-vlc)
If num is not provided, yields information about current and available subtitles and captions tracks for the current stream. For example, for one DVD:

> (vlc-strack)

  -1
  '(("spu-es"
     ("Disable"              . -1)
     ("Track 1 - [Français]" . 14)
     ("Track 2 - [Español]"  . 15)
     ("Closed captions 1"    . 17)
     ("Closed captions 2"    . 18)
     ("Closed captions 3"    . 19)
     ("Closed captions 4"    . 20)))
If num is provided, switches the subtitles/captions to that track.

4.8 Audio Options

4.9 Video Options

procedure

(vlc-fullscreen on? [#:vlc vlc])  void?

  on? : boolean?
  vlc : vlc? = (current-vlc)
Set whether VLC is in fullscreen mode.

4.10 Misc. Info

procedure

(vlc-get-title [#:vlc vlc])  string?

  vlc : vlc? = (current-vlc)
Get the title of the current stream. For example, a particular DVD, might give behavior like:
> (vlc-get-title)
  "WEST_WING_S7_D3"
Warning: Season 7 is not the best season for West Wing.

procedure

(vlc-status [#:vlc vlc])  (list-of (cons/c bytes? bytes?))

  vlc : vlc? = (current-vlc)
Yields an alist of some information about current status. The car of each pair of the alist is a byte string of one of the following attribute names, and the cdr is a byte string of the attribute value:
  • #"new input" – URL of the current playlist item.

  • #"audio volume" – number representing the audio volume.

  • #"state" – play state; possibly including the following values: #"playing", #"paused", #"stopped".

Which attributes are included depends on VLC.

5 Snapshots

procedure

(vlc-snapshot [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Write a snapshot still image of the current video display to a file. See VLC documentation for command line arguments for controlling where and how these files are written, such as snapshot-path.

6 Exiting

procedure

(vlc-shutdown [#:vlc vlc])  void?

  vlc : vlc? = (current-vlc)
Terminate the VLC process in an orderly fashion.

7 Other Operations

In addition to the procedures that correspond to VLC RC commands, there are some additional procedures that are built atop RC commands.

procedure

(wait-for-vlc-active-playing [#:delay delay    
  #:vlc vlc])  void?
  delay : (and/c real? (not/c negative?)) = 0.1
  vlc : vlc? = (current-vlc)
Wait for VLC to be actively playing, by which we mean that the stream has actually started playing, not just the RC status command indicating state: playing, when, say, the DVD hasn’t actually started playing. This seems to be important for some other operations to take effect, such as seeking in some cases.
Note that this procedure is currently protocol-intensive with the RC interface. delay is the number of seconds to pause in between repeatedly sending some RC messages. By default, it is 0.1, meaning one tenth of a second.

8 Known Issues

9 History

10 Legal

Copyright 2012 Neil Van Dyke. This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See http://www.gnu.org/licenses/ for details. For other licenses and consulting, please contact the author. VideoLAN, VLC, and VLC media player are trademarks of VideoLAN.