about summary refs log tree commit homepage
path: root/Documentation/dtas-player_protocol.txt
blob: 42f3bf8270d1d83b22863181b3c99b8449764904 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
% dtas-player_protocol(7) dtas user manual
%

# NAME

dtas-player_protocol - protocol for controling dtas-player

# DESCRIPTION

NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - NOTE

I'm considering a heavy revamp of this protocol.  The "OK" responses for
a lot of commands may not be necessary since this is Unix sockets and
not TCP, and I may move away from a request-response model and towards
an entirely listen/notification model.  I have little experience in
non-TCP-based application protocols, so this is an area of
experimentation for me.

This must stay over Unix sockets because filesystem permissions are
needed to enforce code execution permissions.  dtas-player is really a
shell in disguise, after all.

Protocol feedback greatly appreciated email me at

e@80x24.org

*********************************************************

This gives a specification of the dtas-player protocol over a local Unix
SOCK_SEQPACKET socket.  The dtas-player protocol should NOT be
considered stable at this point and compatibility will break.

Inspiration is taken from MPRIS and MPRIS 2.0 specifications (e.g.
play_pause, play, pause), and there will be a proxy in the future to
support MPRIS/MPRIS 2.0 clients.

The DTAS_PLAYER_SOCK is the standard environment determining the control
socket for dtas-player(1).  This defaults to $HOME/.dtas/player.sock if
unset.

Most low-level commands may be issued using the dtas-ctl(1) command.

Higher-level commands such as dtas-console(1), dtas-sourceedit(1),
dtas-sinkedit(1), and dtas-enq(1) also implement this protocol.

# ARGUMENT TYPES

- BOOLEAN - must be "true" or "false"
- INTEGER - a signed integer in decimal notation (base 10)
- UNSIGNED - an unsigned integer in decimal or hex notation
- ENVNAME - must be a suitable environment variable (setenv(3))
- ENVVALUE - must be a suitable environment variable (setenv(3))
- COMMAND, this may be quoted string passed to sh -c "",
           variable/argument expansion will be performed by the shell
- SOURCENAME - "sox" or "av", more backends may be supported in the future
- TIMESTAMP - a time stamp formatted in HH:MM:SS.FRAC (for seeking)
- TRACKID - a unique unsigned integer in decimal (base-10) representing a
            track in the tracklist
- FILENAME - an expanded pathname relative to / is recommended since
             dtas-player and the client may run in different directories

# VARIABLE EXPANSION

For source and sink "command" arguments, the $SOXFMT and $ECAFMT
environment variables are exported automatically to source to ease
integration with sox(1) and ecasound(1).

Both $SOXFMT and $ECAFMT are based on the configured "format" of
the dtas-player (see below).

For all machines, $SOXFMT defaults to: -ts32 -c2 -r44100
For little-endian machines, $ECAFMT defaults to: -fs32_le,2,44100

# COMMANDS

Commands here should be alphabetized according to `LC_ALL=C sort'

* cd - change the current working directory of the player

* clear - clear current queue (current track/command continues running)
  PENDING: this may be renamed to "queue clear" or "queue-clear"

* cue - display the index/offsets of the file based on the embedded
  cue sheet, if any

* cue next - skip to the next section of the track based on the
  embedded cue sheet.  This may skip to the next track if there is
  no embedded cue sheet or if playing the last (embedded) track

* cue prev - skip to the previous section of the track based on
  the embedded cue sheet.  This may just seek to the beginning
  if there is no embedded cue sheet or if we are playing the first
  (embedded) track.

* cue goto INTEGER - go to the embedded track with cue index denoted
  by INTEGER (0 is first track as returned by "cue").  Negative
  values of INTEGER allows selecting track relative to the last
  track (-1 is the last track, -2 is the penultimate, and so on).

* current - output information about the currently-playing track/command
  in YAML.  The structure of this is unstable and subject to change.

* enq FILENAME - enqueue the given FILENAME for playback
  An expanded (full) pathname relative to '/' is recommended, as
  dtas-player and the client may be in different directories.
  PENDING: this may be renamed to "queue add"

* enq-cmd "COMMAND" - run the following command for playback.
  The COMMAND is expected to output audio in the audio format matching
  the current audio format of the player.  This may be a shell pipeline
  and include multiple commands.  The $SOXFMT and $ECAFMT variables are
  available here.
  PENDING: this may be renamed to "queue add-cmd"

* env ENVTOSET=ENVVALUE ENVTOSET2=ENVVALUE2
  Set environment variables.  This affects all future source/sink
  processes as well as helper commands dtas-player may spawn
  (e.g. soxi(1)).  Environment variables set this way are currently not
  preserved across invocations of dtas-player(1), but may change in the
  future.

* env ENVTOUNSET1# ENVTOUNSET#
  Unset the given environment variable.
  PENDING: the '#' is ugly and inconsistent with the per-sink/source.
  env.

* format FORMATARGS - configure the format between source and sink
  Changing this will affect the $SOXFMT and $ECAFMT environments passed
  to source and sink commands.  Changing this implies a "restart"
  Changing rate to 48000 is probably useful if you plan on playing to some
  laptop sound cards.  In all cases where "bypass" is supported, it
  removes the guarantee of gapless playback as the audio device(s)
  will likely need to be restarted.


    + channels=(UNSIGNED|bypass) - (default: 2 (stereo)) - number of
      channels to use internally.  sox will internally invoke the remix
      effect when decoding.  This supports the value "bypass" (without
      quotes) to avoid the automatic remix effect.  Using "bypass" mode
      removes the guarantee of gapless playback, as the audio device will
      likely need to be restarted, introducing an audible gap.
    + endian=(big|little|swap) - (default: native) - there is probably no
      point in changing this unless you output over a network sink to
      a machine of different endianess.
    + bits=(UNSIGNED|bypass) - (default: implied from type) - sample precision
      (decoded)
      This may be pointless and removed in the future, since the sample
      precision is implied from type.  This supports the value of "bypass"
      to avoid dither/truncation in later stages.
    + rate=(UNSIGNED|bypass) - (default: 44100) - sample rate of audio
      Typical values of rate are 44100, 48000, 88200, 96000.  Not all
      DSP effects are compatible with all sampling rates/channels.
      This supports the value of "bypass" as well to avoid introducing
      software resamplers into the playback chain.
    + type=(s16|s24|s32|u16|u24|u32|f32|f64) - (default: s32)
      change the raw PCM format.  s32 currently offers the best performance
      when only sox/play are used.  f32 may offer better performance if
      piping to/from non-sox applications (e.g. ecasound)

* pause - pause playback
  Player pause state is preserved across dtas-player invocations.

* play - restart playback from pause.  Playback sinks will yield
  control of the audio playback device once no source is playing.

* play_pause - toggle the play/pause state.  This starts playback if
  paused, and pauses playback if playing.

* restart - restarts all processes in the current pipeline.  Playback
  will be momentarily interrupted while this change occurs.  This is
  necessary if one of the commands (e.g. sox or ecasound) or loaded
  libraries (e.g. a LADSPA plugin) is upgraded.

* rg RGARGS - configure ReplayGain support
  All FLOAT values may be adjusted via '+=' or '-=' instead of simple
  assignment ('=').  If RGARGS is empty, the current rg state of
  non-default values will be dumped in YAML.
    + fallback_gain=FLOAT (-6.0) - dB value
      Adjust the volume by this level (usually negative) for tracks
      missing ReplayGain tags.  This is useful when the queue contains
      a mix of tracks with and without ReplayGain tags.
    + fallback_track=BOOLEAN (true)
      When in album_gain mode, fallback to track_gain if the
      REPLAYGAIN_ALBUM_GAIN metadata is missing.
    + mode=(album_gain|track_gain|track_norm|album_norm|off)
      This controls the ReplayGain tag to use.  The *_norm options
      are used for peak normalization and not commonly found in other
      players.
    + preamp=FLOAT (0) - dB value
      Adjust the album_gain or track_gain amount by this value (in dB).
    + norm_level=FLOAT (1.0 == dBFS)
      Controls the level to normalize to when using album_norm or track_norm.

* seek [+-]TIMESTAMP - seek the current track to a specified time.
  This is passed directly as the first argument for the sox(1) "trim"
  command.   See the sox(1) manpage for details.
  Seeking to a relative time is also supported by prefixing the time
  with '+' or '-'

* skip - abort current track/command (via closing the output pipe)
  Running the "clear" command before this will abort playback.

* sink ls - list names of current sinks

* sink cat SINKNAME - dump SINKNAME config in YAML

* sink rm SINKNAME - remove SINKNAME

* sink ed SINKNAME SINKARGS - create/edit SINKNAME
  This currently does not restart running (active) sinks.
  This will stop active sinks if active is set to false, and start
  active sinks if active is set to true.
  See dtas-sinkedit(1) for an example of using this.
    + command=COMMAND - change the command-line used for playback
    + active=BOOLEAN - whether or not the sink will be in use (default: false)
    + env.ENVNAME=ENVVALUE - set ENVNAME to ENVVALUE for the sink process
    + env#ENVNAME - unset ENVNAME in the sink process (only)
    + prio=INTEGER - priority of the sink, lower values run first
    + nonblock=BOOLEAN - drop audio data to avoid holding back other sinks
    + pipe_size=UNSIGNED - set the size of the pipe for the sink (Linux-only)

* source cat SOURCENAME - dump the current source command and env in YAML

* source ed SOURCENAME SOURCEARGS - edit the source parameters.
  This changes here will immediately restart the source process.
  See the code for dtas-sourceedit(1) for an example of using this.
    + command=COMMAND - change the command-line used to decode audio
    + env.ENVNAME=ENVVALUE - set ENVNAME to ENVVALUE for the source process
    + env#ENVNAME - unset ENVNAME in the source process (only)
    + tryorder=INTEGER - lower values are tried first
    PENDING: tryorder here is wrong and may be removed or changed.
    We need to account for at least two variables input file:
        1. input type (flac/opus/mp3/etc)
        2. transport protocol (local FS/http/ftp/sftp/etc)

* state dump [FILENAME]
  Immediately dump the state of the player.  If a FILENAME is specified,
  the state is written to that file.  Otherwise, the default state file
  (configured via DTAS_PLAYER_STATE environment variable, defaulting
  to ~/.dtas/player_state.yml) is written to.  This does not use fsync(2),
  users requiring fsync should open(2) that file and fsync(2) it
  themselves if necessary.

* tl add FILENAME [TRACKID [BOOLEAN]] - add files to the tracklist
  With one arg, adds FILENAME to the head of the tracklist.
  If TRACKID is specified, FILENAME is added immediately after TRACKID
  on the existing tracklist.  The final BOOLEAN argument replaces the
  currently playing track with the newly-added one.
  Returns the TRACKID of the newly added track

* tl remove TRACKID - remove the track with the given TRACKID from
  the track list

* tl get [TRACKIDS]
  returns a list of TRACKIDS mapped to filenames.

* tl goto TRACKID [TIMESTAMP] - plays the given TRACKID
  An optional timestamp may be added to prevent playing the
  same part(s) repeated.y

* tl repeat [BOOLEAN|1] - show/or change repeat status of the tracklist.
  With no args, this will show "true", "false", or "1"
  If set to "1", dtas-player will repeat the current track.

* tl tracks
  returns a list of all TRACKIDS in the tracklist

* watch - adds the client to the passive watch list for notifications.
  It is recommended clients issue no further commands and open
  another client socket to issue non-watch commands.

# CONTACT

All feedback welcome via plain-text mail to <dtas-all@nongnu.org>\
Mailing list archives available at <ftp://lists.gnu.org/dtas-all/>\
No subscription is necessary to post to the mailing list.

# COPYRIGHT

Copyright 2013-2014, Eric Wong <e@80x24.org> and all contributors.\
License: GPLv3 or later <http://www.gnu.org/licenses/gpl-3.0.txt>