Permalink
Browse files

*** 1.43 released ***

	* cplay:
	- partial support for splay
	- commandline arguments: repeat/random (Gerald Stieglbauer)
	- volume fine tuning via +/- (Martin Michlmayr)
	- simplified player framework
	- mark/clear regexp
  • Loading branch information...
1 parent 2f4e87d commit 0a8596db2cd27f66df162ea8a369da470c7cc701 Ulf Betlehem committed with Mar 17, 2001
Showing with 87 additions and 83 deletions.
  1. +10 −1 ChangeLog
  2. +4 −4 README
  3. +4 −1 TODO
  4. +58 −71 cplay
  5. +11 −6 cplay.1
View
@@ -1,3 +1,13 @@
+2001-03-15 Ulf Betlehem <flu@iki.fi>
+
+ *** 1.43 released ***
+
+ * cplay:
+ - partial support for splay
+ - commandline arguments: repeat/random (Gerald Stieglbauer)
+ - volume fine tuning via +/- (Martin Michlmayr)
+ - simplified player framework
+ - mark/clear regexp
2001-01-18 Ulf Betlehem <flu@iki.fi>
*** 1.42 released ***
@@ -225,4 +235,3 @@
1998-04-18 Ulf Betlehem <flu@iki.fi>
* cplay: New file.
-
View
@@ -3,13 +3,14 @@ Description:
to provide a power-user-friendly interface with simple filelist
and playlist control. It is written in Python and can use
either pyncurses or the standard curses module. The list of
- currently supported players include mpg123, ogg123 and sox.
+ supported players include ogg123, mpg123, splay and sox.
Requirements:
- cplay http://www.tf.hut.fi/~flu/cplay/
- python http://www.python.org/
- ogg123 (optional) http://www.vorbis.com/
- mpg123 (optional) http://www.mpg123.org/
+ - splay (optional) http://splay.sourceforge.net/
- sox (optional) http://home.sprynet.com/~cbagwell/sox.html
- fintl (optional) http://www.python.org/sigs/i18n-sig/
- pyncurses (optional) http://pyncurses.sourceforge.net/
@@ -18,13 +19,12 @@ Installation:
make install
Usage:
- cplay [ file | playlist.m3u ] ...
+ cplay [-rR] [ filename | playlist.m3u ] ...
Documentation:
When in doubt, press 'h' for a friendly help page.
If you would like to change the options passed to the actual
- players just edit cplay and change the command string under:
- "class <player>_Player".
+ players just edit cplay and edit the PLAYERS list.
For mpeg streaming, mpg123 v0.59r or later is recommended.
View
@@ -1,5 +1,8 @@
high priority
------------------------------------------
+- madplay support
+- framework for displaying alternative metadata
+- automatic *_Player instantiation
- shuffle/sort marked tracks?
- seek acceleration based on total_time
- toggle time done / time left
@@ -16,13 +19,13 @@ low priority
------------------------------------------
- merge id3 patch
- merge cddb patch
-- splay support
- delwin when resizing
- invert playlist markings
- hierarchical playlists?
misc thoughts
------------------------------------------
+- alsaplayer, xmp, mikmod, others?
- delayed play command (play after current song is finished)
- reset progress when changing song?
- restore xterm title (not possible with aterm, rxvt, etc?)
View
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- python -*-
-__version__ = "cplay 1.43pre3"
+__version__ = "cplay 1.43"
"""
cplay - A curses front-end for various audio players
@@ -37,8 +37,10 @@ import re
try: from ncurses import curses
except ImportError: import curses
-try: import termios, TERMIOS
+try: import termios
except ImportError: termios = None
+try: import TERMIOS
+except ImportError: TERMIOS = termios
try: import locale; locale.setlocale(locale.LC_ALL, "")
except: pass
@@ -939,7 +941,10 @@ class PlaylistWindow(ListWindow):
# ------------------------------------------
class Player:
- def __init__(self):
+ def __init__(self, commandline, files, fps=1):
+ self.commandline = commandline
+ self.re_files = re.compile(files, re.I)
+ self.fps = fps
self.stdout_r, self.stdout_w = os.pipe()
self.stderr_r, self.stderr_w = os.pipe()
self.pathname = None
@@ -953,6 +958,15 @@ class Player:
def is_paused(self):
return self.paused
+ def setup(self, pathname, offset):
+ self.argv = string.split(self.commandline)
+ self.argv[0] = which(self.argv[0])
+ for i in range(len(self.argv)):
+ if self.argv[i] == '%s': self.argv[i] = str(pathname)
+ if self.argv[i] == '%d': self.argv[i] = str(offset*self.fps)
+ self.pathname = pathname
+ return self.argv[0]
+
def play(self):
self.filename = os.path.basename(self.pathname)
app.set_default_status(_("Playing: %s") % self.filename)
@@ -993,28 +1007,6 @@ class Player:
except Exception: pass
quiet or app.set_default_status(_("Stopped: %s") % self.filename)
- ## todo - rewrite?
- def seek(self, direction):
- self.seek_step = self.seek_step or 1
- self.seek_step = self.seek_step * (self.seek_step * direction > 0) + \
- direction
- time_total = self.time_done + self.time_left
- self.time_done = min(time_total, max(0, self.time_done+self.seek_step))
- self.time_left = time_total - self.time_done
- self.show_position()
-
- def set_position(self, time_done, time_left):
- if self.seek_step: return
- if self.time_done == time_done: return
- self.time_done = time_done
- self.time_left = time_left
- self.show_position()
-
- def show_position(self):
- app.counter(self.time_left) # todo - toggle mode
- ratio = self.time_done / (self.time_done + self.time_left + 1.0)
- app.progress(ratio)
-
def parse_stdout(self):
os.read(self.stdout_r, 256)
@@ -1031,52 +1023,40 @@ class Player:
# ------------------------------------------
class ProgressPlayer(Player):
- re_progress = re.compile("Time:\s*(\d+):(\d+).*\[(\d+):(\d+)")
+ re_progress = re.compile("Time.*\s(\d+):(\d+).*\[(\d+):(\d+)")
- def parse_stderr(self):
- m = self.re_progress.search(os.read(self.stderr_r, 256))
+ def parse_fd(self, fd):
+ m = self.re_progress.search(os.read(fd, 256))
if m:
m1, s1, m2, s2 = map(string.atoi, m.groups())
self.set_position(m1*60+s1, m2*60+s2)
-# ------------------------------------------
-class mpg123_Player(ProgressPlayer):
- re_files = re.compile(".*\.mp[123]$", re.I)
- command = "%s -q -v -k %d"
- name = "mpg123"
-
- def setup(self, pathname, offset):
- executable = which(self.name)
- self.argv = string.split(self.command % (executable, offset*38.28))
- self.argv.append(pathname)
- self.pathname = pathname
- return executable or 0
+ def parse_stderr(self):
+ self.parse_fd(self.stderr_r)
-# ------------------------------------------
-class sox_Player(Player):
- re_files = re.compile(".*\.(aiff|au|cdr|wav)$", re.I)
- command = "%s -t ossdsp %s"
- name = "sox"
+ def parse_stdout(self):
+ self.parse_fd(self.stdout_r)
- def setup(self, pathname, offset):
- executable = which(self.name)
- self.argv = string.split(self.command % (executable, DSP))
- self.argv.insert(1, pathname)
- self.pathname = pathname
- return executable or 0
+ ## todo - rewrite?
+ def seek(self, d):
+ self.seek_step = self.seek_step or 1
+ self.seek_step = self.seek_step * (self.seek_step * d > 0) + d
+ time_total = self.time_done + self.time_left
+ self.time_done = min(time_total, max(0, self.time_done+self.seek_step))
+ self.time_left = time_total - self.time_done
+ self.show_position()
-# ------------------------------------------
-class ogg123_Player(ProgressPlayer):
- re_files = re.compile(".*\.ogg$", re.I)
- command = "%s -q -v -d oss -k %d"
- name = "ogg123"
+ def set_position(self, time_done, time_left):
+ if self.seek_step: return
+ if self.time_done == time_done: return
+ self.time_done = time_done
+ self.time_left = time_left
+ self.show_position()
- def setup(self, pathname, offset):
- executable = which(self.name)
- self.argv = string.split(self.command % (executable, offset))
- self.argv.append(pathname)
- self.pathname = pathname
- return executable or 0
+ def show_position(self):
+ app.counter(self.time_left) # todo - toggle mode
+ ratio = self.time_done / (self.time_done + self.time_left + 1.0)
+ app.progress(ratio)
# ------------------------------------------
class Timeout:
@@ -1201,8 +1181,10 @@ class Application:
if not self.player.is_stopped(): self.player.stop()
else: self.play(self.player.pathname, self.player.time_done)
+ ## todo - support seeking when stopped?
def seek(self, direction):
if self.player.is_stopped(): return
+ if not isinstance(self.player, ProgressPlayer): return
if self.seek_tag: self.timeout.remove(self.seek_tag)
self.player.seek(direction)
args = (self.player.pathname, self.player.time_done)
@@ -1254,9 +1236,9 @@ class Application:
# ------------------------------------------
def main():
try:
- opts, args = getopt.getopt(sys.argv[1:], "")
+ opts, args = getopt.getopt(sys.argv[1:], "rR")
except:
- usage = _("Usage: %s [ filename | playlist.m3u ] ...\n")
+ usage = _("Usage: %s [-rR] [ filename | playlist.m3u ] ...\n")
sys.stderr.write(usage % sys.argv[0])
sys.exit(1)
@@ -1270,12 +1252,11 @@ def main():
os.open("/dev/tty", 0)
try:
app.setup()
- if args:
- for arg in args:
- app.win_playlist.append(arg)
- else:
- for line in playlist:
- app.win_playlist.append(line)
+ for opt, optarg in opts:
+ if opt == '-r': app.win_playlist.command_toggle_repeat()
+ if opt == '-R': app.win_playlist.command_toggle_random()
+ for item in args or playlist:
+ app.win_playlist.append(item)
app.run()
except SystemExit:
app.cleanup()
@@ -1285,7 +1266,13 @@ def main():
traceback.print_exc()
# ------------------------------------------
-PLAYERS = [mpg123_Player(), sox_Player(), ogg123_Player()]
+
+PLAYERS = [
+ ProgressPlayer("mpg123 -q -v -k %d %s", ".*\.mp[123]$", 38.28),
+ ProgressPlayer("ogg123 -q -v -d oss -k %d %s", ".*\.ogg$"),
+ ProgressPlayer("splay -f %s", ".*\.mp[123]$"),
+ Player("sox %%s -t ossdsp %s" % DSP, ".*\.(aiff|au|cdr|wav)$")
+ ]
def VALID_SONG(name):
for player in PLAYERS:
View
@@ -3,15 +3,15 @@
.\" It was originally written for Debian GNU/Linux (but may be used
.\" by others).
.\"
-.TH CPLAY 1 "December 2000"
+.TH CPLAY 1 "March 2001"
.SH NAME
.PP
cplay \- a front-end for various audio players
.SH SYNOPSIS
.PP
-\fBcplay\fR [ \fIfile\fP | \fIplaylist.m3u\fP ] ...
+\fBcplay\fR [-options] [ \fIfile\fP | \fIplaylist.m3u\fP ] ...
.SH DESCRIPTION
.PP
@@ -26,18 +26,23 @@ specify an audio file,
.B cplay
automatically adds it to the playlist which can be accessed
by pressing the tabulator key.
-
.PP
Currently, the folloging audio formats are supported: MP3 (through
mpg123), Ogg Vorbis (through ogg123), and WAV, AU, CDR and AIFF
(through sox).
+.SH OPTIONS
+.IP \fB-r
+Toggles playlist \fIrepeat\fP mode
+.IP \fB-R
+Toggles playlist \fIrandom\fP mode
.SH SEE ALSO
.PP
-.BR sox (1),
-.BR mpg123 (1)
-.BR ogg123 (1)
+.BR ogg123 (1),
+.BR mpg123 (1),
+.BR splay (1),
+.BR sox (1)
.SH AUTHOR
.PP

0 comments on commit 0a8596d

Please sign in to comment.