MULTIMEDIA library Multimedia == Description == This document describes facilities provided by HOP for programming Multimedia Web applications. ~~ HOP provides various facilities for programming multimedia applications. It provides functions for parsing images and sounds and functions for controlling music players. All the functions, variables, and classes presented in the document are accessible via the ++multimedia++ library. Here is an example of module that uses this library: ;; Extract the thumbnail of a digital photography. (module thumbnail (library multimedia)) (define-service (thumbnail photo) (when (file-exists? photo) (let ((ex (jpeg-exif photo))) (when (exif? ex) (exif-thumbnail ex))))) The source code of the [[http://hop.inria.fr/hop/weblets/homepage?weblet=hopmusic|HopMusic]] weblet is good example of Web Audio multimedia application implemented in Hop. It uses almost all the features described in the manual page. == Examples == music, exif, m3u == Synopsis == === Server === (class exif ...) (jpeg-exif file-name) (jpeg-exif-comment-set! file-name text) (read-m3u input-port) (write-m3u list input-port) (class id3 ...) (mp3-id3 file-name) (class mixer devices) (class soundcard::mixer device) (mixer-close mix) (mixer-volume-get mix channel) (class music frequency) (class musicproc::music charset) (class mplayer::musicproc path args ao ac) (class mpg123::musicproc path args) (class mpc::music hello host port timeout prefix) (class musicstatus ...) (music-close music) (music-reset! music) (music-closed? music) (music-playlist-get music) (music-playlist-add! music song) (music-playlist-delete! music int) (music-playlist-clear! music) (music-play music [song]) (music-seek music time [song]) (music-stop music) (music-pause music) (music-next music) (music-prev music) (music-crossfade music int) (music-random-set! music bool) (music-repeat-set! music bool) (music-volume-get music) (music-volume-set! music vol) (music-status music) (music-update-status! music status) (music-song music) (music-songpos music) (music-meta music) (music-reset-error! music) (music-event-loop music :ontstate :onmeta :onerror :onvolume) (mpd music input-port output-port database :log) (class mpd-database directories) (hsv->rgb h s v) (hsl->rgb h s l) (rgb->hsv r g b) (rgb->hsl r g l) == Server Definitions == === Photography === ~~ The multimedia library provides functions for accessing the metadata generated by digital camera. ==== ++(class exif ...)++ ==== exif ^ fields ^ access ^ type ^ default value ^ short description ^ | version | r | obj | ++#f++ | exif version. | | jpeg-encoding | r | obj | ++#f++ | | | jpeg-compress | r | obj | ++#f++ | | | comment | r | obj | ++#f++ | | | commentpos | r | obj | ++#f++ | | | commentlen | r | obj | ++#f++ | | | date | r | obj | ++#f++ | | | make | r | obj | ++#f++ | | | model | r | obj | ++#f++ | | | orientation | r | symbol | ++landscape++ | The photograph orientation. | | width | r | obj | ++#f++ | | | height | r | obj | ++#f++ | | | ewidth | r | obj | ++#f++ | | | eheight | r | obj | ++#f++ | | | xresolution | r | obj | ++#f++ | | | yresolution | r | obj | ++#f++ | | | resolution-unit | r | obj | ++#f++ | | | focal-length | r | obj | ++#f++ | | | flash | r | obj | ++#f++ | | | fnumber | r | obj | ++#f++ | | | iso | r | obj | ++#f++ | | | shutter-speed-value | r | obj | ++#f++ | | | exposure-time | r | obj | ++#f++ | | | exposure-bias-value | r | obj | ++#f++ | | | aperture | r | obj | ++#f++ | | | metering-mode | r | obj | ++#f++ | | | cdd-width | r | obj | ++#f++ | | | focal-plane-xres | r | obj | ++#f++ | | | focal-plane-units | r | obj | ++#f++ | | | thumbnail | r | obj | ++#f++ | | | thumbnail-path | r | obj | ++#f++ | | | thumbnail-offset | r | obj | ++#f++ | | | thumbnail-length | r | obj | ++#f++ | | The instance of the ++exif++ class maps the EXIF metadata found in JPEG files into HOP objects. Since all fields are optional they are untyped. ==== ++(jpeg-exif file-name)++ ==== jpeg-exif ^ arguments ^ type ^ short description ^ | file-name | ::string | a file name. | The function ++jpeg-exif++ extracts the [[http://en.wikipedia.org/wiki/Exif|EXIF ]] metadata of a JPEG file as created by digital camera. The argument @var{file-name} is the name of the JPEG file. If the file contains an EXIF section it is returned as an instance of the ++exif++ class. Otherwise, this function returns ++#f++. ==== ++(jpeg-exif-comment-set! file-name text)++ ==== jpeg-exif-comment-set! ^ arguments ^ type ^ short description ^ | file-name | ::string | a file name. | | text | ::string | a user comment. | Set the comment of the EXIF metadata section of the file file-name to ++text++. === Music === The multimedia library provides an extensive set of functions for dealing with music. It provides functions for accessing the metadata of certain music file formats, it provides functions for controlling the volume of the hardware mixers and it provides functions for playing and controlling music playback. ==== Metadata and Playlist ==== ===== ++(read-m3u input-port)++ ===== ===== ++(write-m3u m3u output-port)++ ===== read-m3u write-m3u ^ arguments ^ type ^ short description ^ | input-port | ::input-port | an input port. | | output-port | ::output-port | an output port. | | m3u | ::list | a playlist. | The function ++read-m3u++ reads a playlist expressed in the M3U format from ++input-port++ and returns a list of songs. The function ++write-m3u++ encode such a list encoded in the M3U format to an output port. ===== ++(mp3-id3 file-name)++ ===== mp3-id3 ^ arguments ^ type ^ short description ^ | file-name | ::string | a file name. | Extracts the ID3 tag of MP3 file named ++file-name++. If the file contains an ID3 section, this function returns an instance of the Bigloo class ++id3++. Otherwise, it returns ++#f++. This function is able to deal with all the versions of ID3 encoding. ===== ++(class id3 ...)++ ===== id3 ^ fields ^ access ^ type ^ default value ^ short description ^ | version | r | string | | id3 version. | | title | r | string | | | | artist | r | string | | | | orchestra | r | obj | ++#f++ | | | conductor | r | obj | ++#f++ | | | interpret | r | obj | ++#f++ | | | album | r | string | | | | year | r | string | | | | recording | r | obj | ++#f++ | | | comment | r | string | | | | genre | r | string | | | | track | r | integer | ++-1++ | | | cd | r | obj | ++#f++ | | This class is used to reify the ID3 metadata used in the MP3 format. ==== Mixer ==== HOP proposes various functions and classes for controlling the audio volume of sound cards. ===== ++(class mixer ...)++ ===== mixer ^ fields ^ access ^ type ^ default value ^ short description ^ | devices | r | list | ++()++ | The list of available channels. | ===== ++(class soundcard::mixer ..)++ ===== soundcard ^ fields ^ access ^ type ^ default value ^ short description ^ | devices | r | string | | | The instances of the class ++soundcard++, a subclass of the ++mixer++ class, are used to access physical soundcard as supported by operating systems. The class field ++device++ stands for the name of the system device (e.g., ++"/dev/mixer"++ for the Linux OS). During the initialization of the instance, the device is opened and initialized. ===== ++(mixer-close mix)++ ===== mixer-close ^ arguments ^ type ^ short description ^ | mix | ::mixer | The mixer. | Closes a mixer. ===== ++(mixer-volume-get mix channel)++ ===== ===== ++(mixer-volume-set! mix channel leftv rightv)++ ===== mixer-volume-get mixer-volume-set! ^ arguments ^ type ^ short description ^ | mix | ::mixer | The mixer. | | channel | ::integer | The channel number. | | leftv | ::integer | an integer in the range ++0..100++. | | rightv | ::integer | an integer in the range ++0..100++. | The function ++mixer-volume-get++ returns the left and right volume levels (two values) of the ++channel++ of the mixer ++mix++. The @var{channel} is denoted by its name and is represented as a string of characters. The argument ++mix++ is an instance of the ++mixer++ class. The function ++mixer-volume-set!++ changes the audio level of a mixer channel. ==== Playback ==== HOP supports various functions for playing music. These functions rely on two data structure: //music players// and //music status//. The first ones are used to control player back-ends. The second ones are used to get information about the music being played. The following example shows how a simple music player using either MPlayer, MPG123, or MPC can be programmed with HOP. ===== ++(abstract-class music ...)++ ===== music ^ fields ^ access ^ type ^ default value ^ short description ^ | frequency | r | long | ++2000000++ | | This abstract class is the root class of all music players. ===== ++(abstract-class musicproc::music ...)++ ===== musicproc ^ fields ^ access ^ type ^ default value ^ short description ^ | charset | r | symbol | ++ISO-LATIN-1++ | | This class is used to reify player that are run in an external process. ===== ++(class mplayer::musicproc ...)++ ===== mplayer ^ fields ^ access ^ type ^ default value ^ short description ^ | path | r | string | ++mplayer++ | The binary path to MPLAYER. | | args | r | list | ++'("-vo" "null" "-quiet" "-slave" "-idle"))++ | The default argument list. | | ao | r | obj | ++#unspecified++ | The MPlayer //ao// command line argument. | | ac | r | obj | ++#unspecified++ | The MPlayer //ac// command line argument. | A player based on the external software ++MPlayer++. Creating such a player spawns in background a MPlayer process. ===== ++(class mpg123::musicproc ...)++ ===== mplayer ^ fields ^ access ^ type ^ default value ^ short description ^ | path | r | string | ++mpg123++ | The binary path to MPLAYER. | | args | r | list | ++'("--remote"))++ | The default argument list. | A player based on the external software ++mpg123++. Creating such a player spawns in background a mpg123 process. ===== ++(class mpc::music ...)++ ===== mpc ^ fields ^ access ^ type ^ default value ^ short description ^ | hello | r | obj | ++#f++ | An optional //hello// phrase sent to MPD. | | host | r | string | ++localhost++ | The default MPD host. | | port | r | integer | ++6600++ | The default MPD port. | | timeout | r | integer | ++10008993++ | | | prefix | r/w | bool | ++#f++ | | A MPC client. * ++hello++: an optional string written when the connection is establish with the MPD server. * ++prefix++: an optional path prefix to be removed from music playlist. This is needed because MPD can only play music files registered in is private database. The file names used by MPD are relative a root directory used to fill the database. The ++prefix++ field allows programmer to write portable code that manages play list file names independently of the player selected. ===== ++(class musicstatus ...)++ ===== musicstatus ^ fields ^ access ^ type ^ default value ^ short description ^ | state | r | symbol | ++stop++ | | | volume | r | obj | ++-1++ | | | repeat | r | bool | ++#f++ | | | random | r | bool | ++#f++ | | | playlistid | r | integer | ++-1++ | | | playlistlength | r | integer | ++0++ | | | xfade | r | integer | ++0++ | | | song | r | integer | ++0++ | | | songid | r | integer | ++0++ | | | songpos | r | integer | ++0++ | | | songlength | r | integer | ++0++ | | | bitrate | r | integer | ++0++ | | | khz | r | integer | ++0++ | | | err | r | obj | ++#f++ | | The instances of the class ++musicstatus++ denote that state of a player. ===== ++(music-close music)++ ==== ===== ++(music-closed? music)++ ==== ===== ++(music-reset! music)++ ==== music-close music-closed? music-reset! ^ arguments ^ type ^ short description ^ | music | ::music | The music player. | Closes, resets, and tests the state of a music player. ===== ++(music-playlist-get music)++ ===== ===== ++(music-playlist-add! music song)++ ===== ===== ++(music-playlist-delete! music int)++ ===== ===== ++(music-playlist-clear! music)++ ===== music-playlist-get music-playlist-add! music-playlist-delete! music-playlist-clear! These functions controls the playlist used by a player. * ++music-playlist-get++: returns the list of songs of the current playlist. * ++music-playlist-add!++: adds an extra song at the end of the playlist. * ++music-delete!++: removes the song number ++int++ from the playlist. * ++music-clear!++: erases the whole playlist. ===== ++(music-play music [song])++ ===== ===== ++(music-seek music time [song])++ ===== ===== ++(music-stop music)++ ===== ===== ++(music-pause music)++ ===== ===== ++(music-next music)++ ===== ===== ++(music-prev music)++ ===== music-play music-seek music-stop music-pause music-next music-prev These functions changes the state of the music player. The function ++music-seek++ seeks the playback position to the position ++time++. which is an integer denoting a number of seconds. ===== ++(music-crossfade music int)++ ===== ===== ++(music-random-set! music bool)++ ===== ===== ++(music-repeat-set! music bool)++ ===== music-crossfade music-random-set! music-repeat-set! These functions controls how songs playback should follow each other. ===== ++(music-volume-get music)++ ===== ===== ++(music-volume-set! music vol)++ ===== music-volume-get music-volume-set! Get and set the audio volume of a player. Some player use the native mixer supported by the operating system some others use a software mixer unrelated to the hardware. ===== ++(music-status music)++ ===== ===== ++(music-update-status! music status)++ ===== music-status music-update-status! The function ++music-status++ returns an instance of the ++musicstatus++ class which denotes the state of the player. The function ++music-update-status!++ updates this status. ===== ++(music-song music)++ ===== ===== ++(music-songpos music)++ ===== music-song music-songpos These two functions return the number of the song being played and the position in the song. These functions are somehow redundant with the function ++music-status++ because the status also contains information about the playback song and playback position. However, for some players getting the music song and the playback position is cheaper than getting the whole player status. ===== ++(music-meta music)++ ===== music-meta Returns the metadata the current song. ===== ++(music-reset-error! music)++ ===== music-reset-error! Reset the previous errors detected by a player. ===== ++(music-event-loop music [:onstate] [:onmeta] [:onerror] [:onvolume])++ ===== music-event-loop The function ++music-event-loop++ enable event notifications when the state of a player changes. The keyword arguments are: * :onstate, a function of one parameter. When the player state changes, this function is called with an instance of ++musicstatus++ as actual parameter. * :onmeta, a function of two parameters. This function is called when a metadata is detected in the music currently played. * :onerror, a function of one parameter, invoked when an error is detected. * :onvolume, a function of one parameter, invoked when the volume changes. ==== MPD ==== [[http://www.musicpd.org|Music Player Daemon]] (MPD in short) allows remote access for playing music. MPD is designed for integrating a computer into a stereo system that provides control for music playback over a local network. The Bigloo class ++mpc++ implements a ++mpd++ client. All Bigloo players can be access via the MPD protocol, using the The following example shows how to access a MPlayer music player using the MPD protocol with a simple HOP program: (module mpd (library multimedia pthread)) (define-service (mpd directory) (let ((db (instantiate::mpd-database (directories (list directory)))) (serv (make-server-socket 6600)) (music (instantiate::mplayer))) (let loop () (thread-start! (make-mpd-connection-thread music db sock)) (loop)))) (define (make-mpd-connection-thread music db sock) (instantiate::pthread (body (lambda () (let ((pi (socket-input sock)) (po (socket-output sock))) (input-timeout-set! pi 10000) (output-timeout-set! po 10000) (unwind-protect (mpd music pi po db) (socket-close sock))))))) ===== ++(mpd music input-port output-port database [:log])++ ===== mpd The function ++mpd++ implements a MPD server. It reads commands from the ++input-port++ and write results to ++output-port++. The argument ++database++, an instance of the ++mpd-database++ class, describes the music material that can be delivered by this player. ===== ++(class mpd-database directories)++ ===== mpd-database ^ fields ^ access ^ type ^ default value ^ short description ^ | directories | r | list | ++()++ | The list of repositories. | The field ++directories++ contains the list of the directories that contains music files. === Color === ===== ++(hsv->rgb h s v)++ ===== ===== ++(hsl->rgb h s l)++ ===== ===== ++(rgb->hsv r g b)++ ===== ===== ++(rgb->hsl r g b)++ ===== hsv->rgb hsl->rgb rgb->hsv rgb->hsl These procedures converts from and to HSV, HSL, and RGB representations. The argument ++h++ is an integer in the range ++[0..360]++, the arguments ++s++, ++v++, and ++l++ in the range ++[0..100]++. The arguments ++r++, ++g++, and ++b++ are in the range ++[0..255]++. These procedures returns multiple-values. (multiple-value-bind (r g b) (hsv->rgb 340 34 56) (list r g b)) ,( '=>) (143 94 110) (multiple-value-bind (h s v) (rgb->hsv 255 0 0) (list h s v)) ,( '=>) (0 100 100)