| Jim Turner ( @ 2009-04-22 11:49:00 |
Audacious Patch
I really liked the old, now defunct "xmms" music player software. A fork of it seems to have replaced it called "Audacious". I gave it a try, and it seems to really work and sound well, much better than "vlc". Anyway, a couple of annoyances have crept into it as of the latest version 1.5.1:
1) The "File Open" window pops up when specifying the cdrom (cdda://) as the play target on the command-line.
2) Starting Audacious without a play target (music files, playlist file, url, or cdd*:// device) causes the last played playlist to start up automatically. That's well and good, but I wanted a way to start up Audacious with an empty playlist.
3) For some strange reason, you can stream audio, at least mp3 from a url, but NOT from STDIN?!
I found a patch here that partially addresses (1) here: http://atheme.org/attachments/15/1.5.1-c ommandline-options.patch Thanks Tony Vroon! I applied this, but it did not fix 1 completly, so I developed another patch based from this one to fix (1) and add a "-c/--clear" command-line option to address (2). I also patched the plugin file (stdio.c) to address 3. Whilst I was at it, I decided to also add the ability to pipe in a playlist (list of files/urls to play) into STDIN as well! For piping a song, one needs to append the extension to the STDIN filename ("-) in indicate to Audacious what type of file it's processing. I ended up having to hack several of the plugins, so that it now works (tested) for ogg, wav, and mp3-ish files.
I ended up having to also include the "file://" prefix since otherwise Audacious thinks "-.mp3" is an option. Anyway, these patches are against Audacious v. 1.5.1 (audacious_1.5.1.orig.tar.gz) and Plugins, v. 1.5.1 (audacious-plugins_1.5.1.orig.tar.gz).
To pipe in a song, do:
cat ~/mymusic/coolsong.mp3 | audacious file://-.mp3
To pipe in a play list, do:
ls ~/mymusic | audacious -
Now I can do cool things like stream radio that is in a format that Audacious can't play, like "asf" through Audacious without filling up my hard disk, ie.:
rm -f /tmp/fifo.wav
mkfifo /tmp/fifo.wav
cat /tmp/fifo.wav | audacious file://-.wav &
sleep 1
mplayer -msglevel all=-1 -nojoystick -nolirc http://68.142.72.75:80/citadelcc_WBAP_AM?M SWMExt=.asf -vc null -vo null -ao pcm:waveheader:file=/tmp/fifo.wav &
main.c (diff):
102a103
> gboolean clear;
276a278
> {"clear", 'c', 0, G_OPTION_ARG_NONE, &options.clear, N_("Clear Playlist"), NULL},
291a294,359
> static gboolean
> add2playlist_via_stdin(gpointer unused)
> {
> gchar *filename;
> gchar *current_dir = g_get_current_dir();
> GList *fns = NULL;
> char s[500];
> time_t timeout = 1;
>
> long original = (long)fcntl(0, F_GETFL);
> gboolean dataRead = FALSE;
>
> fcntl(0, F_SETFL, O_NONBLOCK);
> while (!dataRead && (timeout > 0))
> {
> if (fgets(s, 500, stdin) != NULL) {
> dataRead = TRUE;
> } else {
> if (feof(stdin))
> {
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> return FALSE;
> }
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> /* sleep(1); */
> g_usleep(20000);
> timeout--;
> }
> }
> fcntl(0, F_SETFL, original);
> if(dataRead)
> {
> if (strlen(s) > 1 && s[0] != '#') /* filter out the comments*/
> {
> s[strlen(s)-1] = '\0';
> /* if (strlen(s) <= 0) break; */
> if (!strstr(s, "://"))
> {
> if (s[0] == '/')
> filename = g_strdup_printf("file:///%s", s);
> else
> filename = g_strdup_printf("file:///%s/%s",
> current_dir, s);
> fns = g_list_prepend(fns, filename);
> }
> else
> {
> filename = g_strdup(s);
> fns = g_list_prepend(fns, filename);
> }
> drct_pl_add(fns);
> }
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> return TRUE;
> }
> else
> {
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> return TRUE;
> }
> }
>
318c386
< handle_cmd_line_options()
---
> handle_cmd_line_options(gboolean skip)
433c501
< { /* !is_running */
---
> if (!skip) { /* !is_running */
448a517,518
> else if (filenames[i][0] == '-')
> g_idle_add_full(G_PRIORITY_LOW, add2playlist_via_stdin, NULL, NULL);
456c526
< fns = g_list_prepend(fns, filename);
---
> if (filenames[i][0] != '-') fns = g_list_prepend(fns, filename);
489a560,564
> }
> else if (options.clear) /* JWT: ADDED "-c" COMMAND-LINE OPTION TO START UP W/EMPTY PLAYLIST! */
> {
> drct_pl_clear();
> drct_stop();
718c793
< handle_cmd_line_options();
---
> handle_cmd_line_options(TRUE);
737a813,814
> handle_cmd_line_options(FALSE);
>
auddrct.c. (diff):
103,104c103,104
< else
< mainwin_eject_pushed();
---
> /* JWT: PREVENT "Open Files" DIALOG WINDOW POPPING UP WHEN OPENED WITHOUT USER REQUESTING - else
> mainwin_eject_pushed(); */
(plugins) madplug/plugin.c (diff):
263a264,270
> /* JWT: EXCLUDE NON-MP3 EXTENSIONS! */
> if (strstr(filename, "file://-."))
> {
> if ((ext != NULL) && strcasecmp("mp2", ext) && strcasecmp("mp3", ext)
> && strcasecmp("mpg", ext) && strcasecmp("bmu", ext)) return 0;
> }
>
344a352,357
> if (strstr(filename, "file://-.")) /* JWT: EXCLUDE NON-MP3 EXTENSIONS IF STDIN TO AVOID OPEN/READ! */
> {
> gchar *ext = extname(filename);
> if ((ext != NULL) && strcasecmp("mp2", ext) && strcasecmp("mp3", ext)
> && strcasecmp("mpg", ext) && strcasecmp("bmu", ext)) return 0;
> }
(plugins) sndfile/plugin.c (diff):
105c105,118
< snd_file = sf_open_virtual (&sf_virtual_io, SFM_READ, tmp_sfinfo, *vfsfile);
---
> if (filename[7] == '-' && filename[8] == '.') /* JWT: IF stdin "OPEN" DIFFERENTLY - JUST TO GET sndfile OBJECT! */
> {
> if (sndfile == NULL) /* JWT: ONLY OPEN (stdin) IF THIS IS 1ST CALL. */
> {
> memset(&sfinfo, 0, sizeof(sfinfo));
> snd_file = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0);
> sndfile = snd_file;
> }
> snd_file = sndfile;
> }
> else
> {
> snd_file = sf_open_virtual (&sf_virtual_io, SFM_READ, tmp_sfinfo, *vfsfile);
> }
159c172
< close_sndfile (tmp_sndfile, vfsfile);
---
> if (filename[7] != '-' || filename[8] != '.') close_sndfile (tmp_sndfile, vfsfile);
351a365,368
> /* JWT: AVOID (RE-)OPENING stdin! */
> if (strstr(filename, "//-.wav") || strstr(filename, "//-.aiff") || strstr(filename, "//-.au")
> || strstr(filename, "//-.raw")) return TRUE;
>
455c472,474
< if (sfinfo.samplerate > 0)
---
> if (playback->filename[7] == '-' && playback->filename[8] == '.')
> song_length = -1;
> else if (sfinfo.samplerate > 0)
496c515
< sndfile = NULL;
---
> /* JWT:WILL CLOSE AND NULL IN play_loop! sndfile = NULL; */
524c543
< fill_song_tuple(filename, ti);
---
> if (filename[7] != '-' || filename[8] != '.') fill_song_tuple(filename, ti);
533a553,556
> /* JWT: AVOID (RE-)OPENING stdin! */
> if (strstr(filename, "//-.wav") || strstr(filename, "//-.aiff") || strstr(filename, "//-.au")
> || strstr(filename, "//-.raw")) return TRUE;
>
(plugins) vorbis/vorbis.c (diff):
96a97,103
> ov_callbacks vorbis_callbacks_stdin = {
> ovcb_read,
> NULL,
> NULL,
> NULL
> };
>
150c157,159
< result = ov_test_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks);
---
> if (!strstr(filename, "//-.ogg") && !strstr(filename, "//-.ogm")) /* JWT: FILE IS NOT stdin */
> {
> result = ov_test_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks);
152,153c161,162
< switch (result) {
< case OV_EREAD:
---
> switch (result) {
> case OV_EREAD:
155c164
< g_message("** vorbis.c: Media read error: %s", filename);
---
> g_message("** vorbis.c: Media read error: %s", filename);
157,160c166,169
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_ENOTVORBIS:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_ENOTVORBIS:
162c171
< g_message("** vorbis.c: Not Vorbis data: %s", filename);
---
> g_message("** vorbis.c: Not Vorbis data: %s", filename);
164,167c173,176
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_EVERSION:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_EVERSION:
169c178
< g_message("** vorbis.c: Version mismatch: %s", filename);
---
> g_message("** vorbis.c: Version mismatch: %s", filename);
171,174c180,183
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_EBADHEADER:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_EBADHEADER:
176,177c185,186
< g_message("** vorbis.c: Invalid Vorbis bistream header: %s",
< filename);
---
> g_message("** vorbis.c: Invalid Vorbis bistream header: %s",
> filename);
179,182c188,191
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_EFAULT:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_EFAULT:
184,185c193,194
< g_message("** vorbis.c: Internal logic fault while reading %s",
< filename);
---
> g_message("** vorbis.c: Internal logic fault while reading %s",
> filename);
187,194c196,203
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case 0:
< break;
< default:
< break;
< }
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case 0:
> break;
> default:
> break;
> }
196,197c205,207
< ov_clear(&vfile); /* once the ov_open succeeds, the stream belongs to
< vorbisfile.a. ov_clear will fclose it */
---
> ov_clear(&vfile); /* once the ov_open succeeds, the stream belongs to
> vorbisfile.a. ov_clear will fclose it */
> }
286,290c296,312
< if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
< vorbis_callbacks.close_func(datasource);
< g_mutex_unlock(vf_mutex);
< playback->eof = TRUE;
< goto play_cleanup;
---
> if (filename[7] == '-' && filename[8] == '.') /* JWT: FILE IS stdin */
> {
> if (ov_open_callbacks(datasource, &vf, NULL, 0, vorbis_callbacks_stdin) < 0) {
> vorbis_callbacks.close_func(datasource);
> g_mutex_unlock(vf_mutex);
> playback->eof = TRUE;
> goto play_cleanup;
> }
> }
> else
> {
> if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
> vorbis_callbacks.close_func(datasource);
> g_mutex_unlock(vf_mutex);
> playback->eof = TRUE;
> goto play_cleanup;
> }
294c316
< if (aud_vfs_is_streaming(fd->fd))
---
> if ((filename[7] == '-' && filename[8] == '.') || aud_vfs_is_streaming(fd->fd))
296c318
< else
---
> else /* JWT: FILE IS AN ACTUAL FILE, NOT stdin OR A STREAM. */
565c587
< if (aud_vfs_is_streaming(vfd->fd))
---
> if ((filename[7] == '-' && filename[8] == '.') || aud_vfs_is_streaming(vfd->fd))
567c589
< else
---
> else /* JWT: FILE IS AN ACTUAL FILE, NOT stdin OR A STREAM. */
623,626c645,650
< if (ov_open_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
< aud_vfs_fclose(stream);
< return NULL;
< }
---
> if (filename[7] != '-' || filename[8] != '.') /* JWT: FILE IS NOT stdin */
> {
> if (ov_open_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
> aud_vfs_fclose(stream);
> return NULL;
> }
628c652
< tuple = get_aud_tuple_for_vorbisfile(&vfile, filename);
---
> tuple = get_aud_tuple_for_vorbisfile(&vfile, filename);
630,634c654,658
< /*
< * once the ov_open succeeds, the stream belongs to
< * vorbisfile.a. ov_clear will fclose it
< */
< ov_clear(&vfile);
---
> /*
> * once the ov_open succeeds, the stream belongs to
> * vorbisfile.a. ov_clear will fclose it
> */
> ov_clear(&vfile);
636c660,663
< return tuple;
---
> return tuple;
> }
>
> return NULL;
(plugins) stdio/stdio.c (diff):
86c86,89
< file->handle = fopen(decpath != NULL ? decpath : path, mode);
---
> if (decpath[0] == '/' && decpath[1] == '-' && decpath[2] == '.') /* JWT: TREAT "file://-.xxx" as "-" (stdin)! */
> file->handle = stdin;
> else
> file->handle = fopen(decpath != NULL ? decpath : path, mode);
108a112,113
> if (strstr(file->uri, "file://-.")) return ret; /* JWT: DON'T CLOSE STDIN! (file://-.xxx)! */
>
Recompiled from source obtained here: http://packages.debian.org/source/testin g/audacious
Also found this cool streaming radio site while testing: http://scfire-ntc-aa03.stream.aol.com:80/s tream/1018
I really liked the old, now defunct "xmms" music player software. A fork of it seems to have replaced it called "Audacious". I gave it a try, and it seems to really work and sound well, much better than "vlc". Anyway, a couple of annoyances have crept into it as of the latest version 1.5.1:
1) The "File Open" window pops up when specifying the cdrom (cdda://) as the play target on the command-line.
2) Starting Audacious without a play target (music files, playlist file, url, or cdd*:// device) causes the last played playlist to start up automatically. That's well and good, but I wanted a way to start up Audacious with an empty playlist.
3) For some strange reason, you can stream audio, at least mp3 from a url, but NOT from STDIN?!
I found a patch here that partially addresses (1) here: http://atheme.org/attachments/15/1.5.1-c
I ended up having to also include the "file://" prefix since otherwise Audacious thinks "-.mp3" is an option. Anyway, these patches are against Audacious v. 1.5.1 (audacious_1.5.1.orig.tar.gz) and Plugins, v. 1.5.1 (audacious-plugins_1.5.1.orig.tar.gz).
To pipe in a song, do:
cat ~/mymusic/coolsong.mp3 | audacious file://-.mp3
To pipe in a play list, do:
ls ~/mymusic | audacious -
Now I can do cool things like stream radio that is in a format that Audacious can't play, like "asf" through Audacious without filling up my hard disk, ie.:
rm -f /tmp/fifo.wav
mkfifo /tmp/fifo.wav
cat /tmp/fifo.wav | audacious file://-.wav &
sleep 1
mplayer -msglevel all=-1 -nojoystick -nolirc http://68.142.72.75:80/citadelcc_WBAP_AM?M
main.c (diff):
102a103
> gboolean clear;
276a278
> {"clear", 'c', 0, G_OPTION_ARG_NONE, &options.clear, N_("Clear Playlist"), NULL},
291a294,359
> static gboolean
> add2playlist_via_stdin(gpointer unused)
> {
> gchar *filename;
> gchar *current_dir = g_get_current_dir();
> GList *fns = NULL;
> char s[500];
> time_t timeout = 1;
>
> long original = (long)fcntl(0, F_GETFL);
> gboolean dataRead = FALSE;
>
> fcntl(0, F_SETFL, O_NONBLOCK);
> while (!dataRead && (timeout > 0))
> {
> if (fgets(s, 500, stdin) != NULL) {
> dataRead = TRUE;
> } else {
> if (feof(stdin))
> {
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> return FALSE;
> }
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> /* sleep(1); */
> g_usleep(20000);
> timeout--;
> }
> }
> fcntl(0, F_SETFL, original);
> if(dataRead)
> {
> if (strlen(s) > 1 && s[0] != '#') /* filter out the comments*/
> {
> s[strlen(s)-1] = '\0';
> /* if (strlen(s) <= 0) break; */
> if (!strstr(s, "://"))
> {
> if (s[0] == '/')
> filename = g_strdup_printf("file:///%s", s);
> else
> filename = g_strdup_printf("file:///%s/%s",
> current_dir, s);
> fns = g_list_prepend(fns, filename);
> }
> else
> {
> filename = g_strdup(s);
> fns = g_list_prepend(fns, filename);
> }
> drct_pl_add(fns);
> }
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> return TRUE;
> }
> else
> {
> g_list_foreach(fns, (GFunc) g_free, NULL);
> g_list_free(fns);
> return TRUE;
> }
> }
>
318c386
< handle_cmd_line_options()
---
> handle_cmd_line_options(gboolean skip)
433c501
< { /* !is_running */
---
> if (!skip) { /* !is_running */
448a517,518
> else if (filenames[i][0] == '-')
> g_idle_add_full(G_PRIORITY_LOW, add2playlist_via_stdin, NULL, NULL);
456c526
< fns = g_list_prepend(fns, filename);
---
> if (filenames[i][0] != '-') fns = g_list_prepend(fns, filename);
489a560,564
> }
> else if (options.clear) /* JWT: ADDED "-c" COMMAND-LINE OPTION TO START UP W/EMPTY PLAYLIST! */
> {
> drct_pl_clear();
> drct_stop();
718c793
< handle_cmd_line_options();
---
> handle_cmd_line_options(TRUE);
737a813,814
> handle_cmd_line_options(FALSE);
>
auddrct.c. (diff):
103,104c103,104
< else
< mainwin_eject_pushed();
---
> /* JWT: PREVENT "Open Files" DIALOG WINDOW POPPING UP WHEN OPENED WITHOUT USER REQUESTING - else
> mainwin_eject_pushed(); */
(plugins) madplug/plugin.c (diff):
263a264,270
> /* JWT: EXCLUDE NON-MP3 EXTENSIONS! */
> if (strstr(filename, "file://-."))
> {
> if ((ext != NULL) && strcasecmp("mp2", ext) && strcasecmp("mp3", ext)
> && strcasecmp("mpg", ext) && strcasecmp("bmu", ext)) return 0;
> }
>
344a352,357
> if (strstr(filename, "file://-.")) /* JWT: EXCLUDE NON-MP3 EXTENSIONS IF STDIN TO AVOID OPEN/READ! */
> {
> gchar *ext = extname(filename);
> if ((ext != NULL) && strcasecmp("mp2", ext) && strcasecmp("mp3", ext)
> && strcasecmp("mpg", ext) && strcasecmp("bmu", ext)) return 0;
> }
(plugins) sndfile/plugin.c (diff):
105c105,118
< snd_file = sf_open_virtual (&sf_virtual_io, SFM_READ, tmp_sfinfo, *vfsfile);
---
> if (filename[7] == '-' && filename[8] == '.') /* JWT: IF stdin "OPEN" DIFFERENTLY - JUST TO GET sndfile OBJECT! */
> {
> if (sndfile == NULL) /* JWT: ONLY OPEN (stdin) IF THIS IS 1ST CALL. */
> {
> memset(&sfinfo, 0, sizeof(sfinfo));
> snd_file = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0);
> sndfile = snd_file;
> }
> snd_file = sndfile;
> }
> else
> {
> snd_file = sf_open_virtual (&sf_virtual_io, SFM_READ, tmp_sfinfo, *vfsfile);
> }
159c172
< close_sndfile (tmp_sndfile, vfsfile);
---
> if (filename[7] != '-' || filename[8] != '.') close_sndfile (tmp_sndfile, vfsfile);
351a365,368
> /* JWT: AVOID (RE-)OPENING stdin! */
> if (strstr(filename, "//-.wav") || strstr(filename, "//-.aiff") || strstr(filename, "//-.au")
> || strstr(filename, "//-.raw")) return TRUE;
>
455c472,474
< if (sfinfo.samplerate > 0)
---
> if (playback->filename[7] == '-' && playback->filename[8] == '.')
> song_length = -1;
> else if (sfinfo.samplerate > 0)
496c515
< sndfile = NULL;
---
> /* JWT:WILL CLOSE AND NULL IN play_loop! sndfile = NULL; */
524c543
< fill_song_tuple(filename, ti);
---
> if (filename[7] != '-' || filename[8] != '.') fill_song_tuple(filename, ti);
533a553,556
> /* JWT: AVOID (RE-)OPENING stdin! */
> if (strstr(filename, "//-.wav") || strstr(filename, "//-.aiff") || strstr(filename, "//-.au")
> || strstr(filename, "//-.raw")) return TRUE;
>
(plugins) vorbis/vorbis.c (diff):
96a97,103
> ov_callbacks vorbis_callbacks_stdin = {
> ovcb_read,
> NULL,
> NULL,
> NULL
> };
>
150c157,159
< result = ov_test_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks);
---
> if (!strstr(filename, "//-.ogg") && !strstr(filename, "//-.ogm")) /* JWT: FILE IS NOT stdin */
> {
> result = ov_test_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks);
152,153c161,162
< switch (result) {
< case OV_EREAD:
---
> switch (result) {
> case OV_EREAD:
155c164
< g_message("** vorbis.c: Media read error: %s", filename);
---
> g_message("** vorbis.c: Media read error: %s", filename);
157,160c166,169
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_ENOTVORBIS:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_ENOTVORBIS:
162c171
< g_message("** vorbis.c: Not Vorbis data: %s", filename);
---
> g_message("** vorbis.c: Not Vorbis data: %s", filename);
164,167c173,176
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_EVERSION:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_EVERSION:
169c178
< g_message("** vorbis.c: Version mismatch: %s", filename);
---
> g_message("** vorbis.c: Version mismatch: %s", filename);
171,174c180,183
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_EBADHEADER:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_EBADHEADER:
176,177c185,186
< g_message("** vorbis.c: Invalid Vorbis bistream header: %s",
< filename);
---
> g_message("** vorbis.c: Invalid Vorbis bistream header: %s",
> filename);
179,182c188,191
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case OV_EFAULT:
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case OV_EFAULT:
184,185c193,194
< g_message("** vorbis.c: Internal logic fault while reading %s",
< filename);
---
> g_message("** vorbis.c: Internal logic fault while reading %s",
> filename);
187,194c196,203
< g_mutex_unlock(vf_mutex);
< return FALSE;
< break;
< case 0:
< break;
< default:
< break;
< }
---
> g_mutex_unlock(vf_mutex);
> return FALSE;
> break;
> case 0:
> break;
> default:
> break;
> }
196,197c205,207
< ov_clear(&vfile); /* once the ov_open succeeds, the stream belongs to
< vorbisfile.a. ov_clear will fclose it */
---
> ov_clear(&vfile); /* once the ov_open succeeds, the stream belongs to
>
> }
286,290c296,312
< if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
< vorbis_callbacks.close_func(datasource);
< g_mutex_unlock(vf_mutex);
< playback->eof = TRUE;
< goto play_cleanup;
---
> if (filename[7] == '-' && filename[8] == '.') /* JWT: FILE IS stdin */
> {
> if (ov_open_callbacks(datasource, &vf, NULL, 0, vorbis_callbacks_stdin) < 0) {
> vorbis_callbacks.close_func(datasource);
> g_mutex_unlock(vf_mutex);
> playback->eof = TRUE;
> goto play_cleanup;
> }
> }
> else
> {
> if (ov_open_callbacks(datasource, &vf, NULL, 0, aud_vfs_is_streaming(fd->fd) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
> vorbis_callbacks.close_func(datasource);
> g_mutex_unlock(vf_mutex);
> playback->eof = TRUE;
> goto play_cleanup;
> }
294c316
< if (aud_vfs_is_streaming(fd->fd))
---
> if ((filename[7] == '-' && filename[8] == '.') || aud_vfs_is_streaming(fd->fd))
296c318
< else
---
> else /* JWT: FILE IS AN ACTUAL FILE, NOT stdin OR A STREAM. */
565c587
< if (aud_vfs_is_streaming(vfd->fd))
---
> if ((filename[7] == '-' && filename[8] == '.') || aud_vfs_is_streaming(vfd->fd))
567c589
< else
---
> else /* JWT: FILE IS AN ACTUAL FILE, NOT stdin OR A STREAM. */
623,626c645,650
< if (ov_open_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
< aud_vfs_fclose(stream);
< return NULL;
< }
---
> if (filename[7] != '-' || filename[8] != '.') /* JWT: FILE IS NOT stdin */
> {
> if (ov_open_callbacks(fd, &vfile, NULL, 0, aud_vfs_is_streaming(stream) ? vorbis_callbacks_stream : vorbis_callbacks) < 0) {
> aud_vfs_fclose(stream);
> return NULL;
> }
628c652
< tuple = get_aud_tuple_for_vorbisfile(&vfile, filename);
---
> tuple = get_aud_tuple_for_vorbisfile(&vfile, filename);
630,634c654,658
< /*
< * once the ov_open succeeds, the stream belongs to
< * vorbisfile.a. ov_clear will fclose it
< */
< ov_clear(&vfile);
---
> /*
> * once the ov_open succeeds, the stream belongs to
> * vorbisfile.a. ov_clear will fclose it
> */
> ov_clear(&vfile);
636c660,663
< return tuple;
---
> return tuple;
> }
>
> return NULL;
(plugins) stdio/stdio.c (diff):
86c86,89
< file->handle = fopen(decpath != NULL ? decpath : path, mode);
---
> if (decpath[0] == '/' && decpath[1] == '-' && decpath[2] == '.') /* JWT: TREAT "file://-.xxx" as "-" (stdin)! */
> file->handle = stdin;
> else
> file->handle = fopen(decpath != NULL ? decpath : path, mode);
108a112,113
> if (strstr(file->uri, "file://-.")) return ret; /* JWT: DON'T CLOSE STDIN! (file://-.xxx)! */
>
Recompiled from source obtained here: http://packages.debian.org/source/testin
Also found this cool streaming radio site while testing: http://scfire-ntc-aa03.stream.aol.com:80/s