Release [Rebirth Competition] Pstorytime - Console audiobook player


ankan

Still Fresh
Joined
Oct 7, 2011
Messages
5
Let me introduce to you Pstorytime.


A while before the pandora rebirth competition went live I started working on an audiobook player that behaves the way I want. This is the result. Since the competition started I thought I'd release it as an entry. The intention has always been to run this on my pandora, though I haven't received mine yet. It should all work equally well on any other GNU/Linux device (so far only tested on Debian Squeeze.)


This is a general console application and is not directly connected to any shoulder buttons or such. But pstorytime can be controlled by writing commands to a pipe, so if you can find a program that listens for those buttons and runs custom commands you are ready to go.



Code:
pstorytime

----------

pstorytime is a logging console audiobook player based on gstreamer with a

curses interface. It stores all events like play, pause and seek together with

walltime, filename and position in file. It also autosaves the position while

playing to recover from crashes without loosing the position. This allows the

user to retrace his/her steps and minimizes the risk of getting lost.


Furthermore, it treats all files as a continuous stream so that seeking can be

made seamlessly between different files.


Dependencies

------------

* python    - Only tested with python 2.

* argparse  - Included in python >=2.7 and >=3.1.

* pygst 	- Python gstreamer bindings.

* gstreamer - Including any codecs which you wish to be able to use.


Installation

------------

> python setup.py build

> sudo setup.py install


License

-------

GNU General Public License: [url="http://www.gnu.org/licenses/gpl-3.0.txt"]http://www.gnu.org/l...ses/gpl-3.0.txt[/url]



And a few screenshots.



manualseek.png

You can enter a position to seek to, or a distance to seek. (In this case 10 minutes forward.)



select.png

Or select a position you have already been at and seek there.



fileseek.png

Or seek to a certain file. In this case to 1 hour and 30 minutes into that file.



And some help output (which happens to be quite a lot to read.)



Code:
usage: pstorytime [-h] [--extensions EXT] [--autolog-interval SECS]

                  [--backtrack SECS] [--cmdpipe [PATH]] [--playlog-file PATH]

                  [--conf-dir PATH] [--conf [PATH]] [--lastdir-file [PATH]]

                  [--autoplay BOOL] [--autoquit BOOL] [--loop N]

                  [--volume VOL] [--default-bindings BOOL] [--bind KEY EVENT]

                  [--unbind KEY] [--event-len N] [--keytime MSECS]

                  [--errortime MSECS] [-v] [--gst-pipeline STR]

                  [--gst-link FROM TO]

                  [path] [position]


pstorytime is a logging console audiobook player based on gstreamer with

a curses interface. It stores all events like play, pause and seek

together with walltime, filename and position in file. It also

autosaves the position while playing to recover from crashes without

loosing the position. This allows the user to retrace his/her steps and

minimizes the risk of getting lost.


Furthermore, it treats all files as a continuous stream so that seeking

can be made seamlessly between different files.


positional arguments:

  path                  Audiobook directory, possibly including a file to

                        start playing at. (Default: Load last directory.)

  position              Position to start playing at. See section on

                        positions. (Default: None)


optional arguments:

  -h, --help            show this help message and exit

  --extensions EXT      Comma separated list of additional extensions to treat

                        as audiobook files. (Default: None)

  --autolog-interval SECS

                        How often (in seconds) the position should be

                        autosaved so that the position can be recovered upon

                        crashes, including loss of power etc. (Default: 60)

  --backtrack SECS      How far (in seconds) to automatically backtrack after

                        pausing. (Default: 10)

  --cmdpipe [PATH]      Optional path to a pipe that commands are read from

                        relative to current directory. If no path is given,

                        the cmdpipe is disabled. See section on paths.

                        (Default: {conf}/cmdpipe)

  --playlog-file PATH   Path to the file to save playlog in relative to

                        current directory. See section on paths. (Default:

                        {conf}/logs/{audiobook}/.playlog)

  --conf-dir PATH   	Configuration directory (Default: ~/.pstorytime)

  --conf [PATH] 		Path to main configuration file relative to current

                        directory. If no path is given, the main configuration

                        file is disabled. This option has no effect if placed

                        in the main configuration file. See section on paths.

                        (Default: {conf}/config)

  --lastdir-file [PATH]

                        Path to the file where the last loaded directory is

                        stored. If no path is given, the use of this file is

                        disabled and the current directory will always be used

                        instead. See section on paths. Using the {audiobook}

                        does not make much sense since it is not yet known.

                        (Default: {conf}/lastdir)

  --autoplay BOOL   	Start playing when the audiobook is started. (Default:

                        False)

  --autoquit BOOL   	Quit when the audiobook ends and the player is not

                        looping any more. (Default: False)

  --loop N              Number of times to continue playing from the beginning

                        when the audiobook ends. Negative number for

                        infinitely many times. (Default: 0)

  --volume VOL          Playback volume as a float between 0 and 10. (Default:

                        1.0)

  --default-bindings BOOL

                        Load default bindings. Otherwise all bindings need to

                        be added manually. (Default: True)

  --bind KEY EVENT      Add new binding from key to event. Key names are

                        displayed in the program when pressed, possible events

                        are listed in its own section.

  --unbind KEY          Remove binding for the given key. Key names are

                        displayed in the program when pressed.

  --event-len N 		Number of characters to display of event names in the

                        playlog. (Default: 8)

  --keytime MSECS   	Number of milliseconds to display the name of the last

                        key pressed. (Default: 1000)

  --errortime MSECS 	Number of milliseconds to display the last error

                        message, set it to a negative value to show it

                        forever. (Default: 5000)

  -v, --version 		Show version information.

  --gst-pipeline STR    The gstreamer pipeline to use. Should contain a

                        filesrc and volume component named file-source and

                        volume-control respectively. (Default: filesrc name

                        =file-source ! decodebin2 name=decoder identity

                        name=postdecode ! audioconvert ! audioresample !

                        volume name=volume-control ! autoaudiosink)

  --gst-link FROM TO    Automatically add links between given pairs of

                        components if possible. (Default: decoder ->

                        postdecode)


If -- is used as an argument, no more optional arguments are parsed.

The rest are expected to be positional.


Paths can contain the strings {conf} and {audiobook}. They are replaced

with the absolute path to the configuration directory and the audiobook

directory respectively. The tilde character is expanded as usual to the

users home directory. Arguments can be placed in the main configuration

file or in any file specified on the commandline prefixed by an @ sign.

Though {conf} and {audiobook} are not expanded in such paths.


Available events (and default bindings):

  up                Move one line up. (KEY_UP, k)

  down              Move one line down. (KEY_DOWN, j)

  ppage 			Move one page up, same as up when in error log.

                    (KEY_PPAGE)

  npage 			Move one page down, same as down when in error log.

                    (KEY_NPAGE)

  begin 			Go to first line of list. (KEY_HOME)

  end   			Go to end of list. (KEY_END)

  next_view 		Change to next view. (^I = Tab)

  playlog_view      Change to playlog view. (p)

  filelist_view 	Change to filelist view. (f)

  errorlog_view 	Change to errorlog view. (e)

  select [POS]      Jump to the currently selected entry. Optionally

                    with an absolute or relative position to jump to in

                    regard to the given file/log entry. (^J = Return:

                    select {b})

  timer [TIME]      Pause playback the next time a certain time of day

                    is reached. The time can be either absolute or

                    relative just like file positions. If no time is

                    given, the timer is stopped. (t: timer {b}; play,

                    T: timer)

  buffer store STR  Add the given string to the input buffer. (0-9, :, +, -)

  buffer erase      Erase a character from the input buffer. (KEY_BACKSPACE)

  buffer clear      Clear the input buffer. (=)

  seek POS          Seek to an absolute or relative position.

                    (KEY_LEFT, h: seek -10, KEY_RIGHT, l: seek +10)

  dseek POS 		Seek to a relative position. Absolute positions are

                    also treated as relative positions.

  stepfile INT      Jump to a different file. The integer indicates

                    an index relative to the current file. For example,

                    -1, 0 and 1 indicates the previous, the current and

                    the next file respectively.

  jumpfile INT      Seek to the beginning of the specified file,

                    indexed from 1 and up.

  volume FLOAT      Change volume. An absolute value is an float

                    between 0.0 and 10.0. The number can be prepended

                    with a + or - to change the volume relative to the

                    current one. (u: volume +0.1, d: volume -0.1)

  dvolume FLOAT 	Relatively change the volume. Same as "volume" but

                    it is always treated as a relative change.

  play              Start playback. (t: timer {b}; play)

  pause 			Pause playback.

  play_pause        Toggle play/pause. (" " = Space)

  redraw            Force redraw of the interface. (^L)

  resize            Recompute layout and redraw.

  mark NAME 		Add a bookmark with the given name, the name may

                    not include whitespace.. (*: mark *)

  quit              Quit pstorytime. (q, ^C)


Events may contain the string {b} which is replaced with the current

contents of the input buffer. Multiple events can be sequenced by

separating them by a semi-colon and, if entered through the command

pipe, by placing them on separate lines. When the events are sequenced

by a semi colon and an event fails, the rest of the events on that line

will be ignored.


A position can optionally start or end with a + or - which indicates

that it is a relative position. This is followed or preceded by a colon

separated list of integers given as HOURS:MINUTES:SECONDS, where some

entries may be omitted. Note that the relative position three minutes

can be given in a number of different ways, including +3:00, +3:0,

+180, 1:120+, 0:3:0+ and 0:03:00+.


Edit: The forum has obviously messed up the formatting a bit. The real thing looks better.
 
Last edited by a moderator:
What does "logging" mean in this context?

That every time you start playing, pause, seek etc an entry is added to a play log (as seen in the first two screenshots.) This log contains walltime, what happened and position in the audiobook stream. This log is saved in a file and loaded the next time you open that audiobook. You can easily backtrack if you happen to fall asleep while listening. The program can tell you when you pressed play most recently.


If your machine crashed the last time you were playing a log entry is available for the last time an autosave took place. At which point you know around when that crash took place. This is different from the single position in each file (or audiobook depending on program) that is usually stored. So if you by accident happen to seek to the beginning of the file without remembering where you were, it is easy to find your way back without a tedious manual search through a file that can be over ten hours long.


It is also possible to figure out what you were listening to at a certain time if you so wish.
 
I like the look of this. I don't listen to a lot of audiobooks, but I wonder if this would also function well as a more general purpose audio player? Not that we're starved of audio players on the platform, but your logging implementation sounds cool. That in conjunction with gapless playback (assuming it does that) could be very handy for live/DJ sets, mix compilations etc.


Unfortunately I'm not able to get it running. I've successfully run the first two commands in the readme (python build & install) but I'm unsure where to go from there. Do I need to install that opkg stuff as well, or is that just in there for reference?


Perhaps someone could team up with you to create a PND. Or, hopefully, you'll get your hardware before too long.
 
I like the look of this. I don't listen to a lot of audiobooks, but I wonder if this would also function well as a more general purpose audio player? Not that we're starved of audio players on the platform, but your logging implementation sounds cool. That in conjunction with gapless playback (assuming it does that) could be very handy for live/DJ sets, mix compilations etc.


Unfortunately I'm not able to get it running. I've successfully run the first two commands in the readme (python build & install) but I'm unsure where to go from there. Do I need to install that opkg stuff as well, or is that just in there for reference?


Perhaps someone could team up with you to create a PND. Or, hopefully, you'll get your hardware before too long.

Hello Gruso, and thank you for your interest. I am happy to help out.


You are most likely missing some dependencies. So yes, you will have to run some of the opkg-commands and follow the other instructions. Since build and install worked, you already seem to have python-setuptools, which I didn't. But you will need the others. The pandora-specific instructions in the readme are what I had to do to make it run on my own fresh-from-factory pandora.


I guess I could create a PND, but from what I have seen a PND is intended to be an image containing a program and dependencies that is mounted when a program is started. The program is uninstalled by removing the PND-file, that could be stored anywhere. But how should this work together with a console application? One possibility is to mount and start a terminal with the program in the path, you need shell access to specify which audiobook to load. But this doesn't really sound like a good idea, it kinda gives me the itch. It would be better if it is accessible from any terminal.


The other option is to provide a PND installer, but this would have to automatically modify the firmware in the way described in the readme. It is also hard to provide any sane way of reverting the changes made by the installer, since the dependencies could be used by other programs. Sure, the instructions from the readme could also be used by a power-user uninstall it.


Are there any other programs using a PND as an installer in this way? That is, programs less mainstream than the community codec pack which is at least semi-official.


Is it a good idea to start releasing PNDs that does this, or is there any other way of using a PND that is more suitable to console applications? I am really new to pandora and Ångström in general, though I do have experience from other distros.
 
Just lauch a console from the startupscript with your application :)


Maybe add a loader for audiobooks.


Edit: An installer isn't really needed here I think.
 
Last edited by a moderator:
Back
Top