Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Glad it's working more or less like you were hoping.
On the scripting front, let me say this:
I stopped looking into the scripting option when 273 made the post about IDJC. The meager amount of info I gathered was that you have two scripting language options with ices: Perl and Python. So, when you compiled ices originally, you must have the dev packages installed for one of those two.
Furthermore, the Perl/Python script must have certain predefined hooks/functions that ices expects... callbacks if you're familiar with the term.
The thing is, I know Python allows for outside system calls to another program. So if you can get all the functionality you want in language XYZ, you'll just have to struggle with setting up a Python script to act an an intermediary between ices and your language of choice.
Meh, I seriously dislike Perl and Python. Maybe I could find Perl tolerable if I tried it again, but the last time I tried was 10 years ago, I forgot almost everything. Python about 8 years and I didn't like it at all. The only languages I am fully willing to accept are Tcl and shell.
But that's fine, I will have to investigate the details on Ices again, then see what I can do. Still haven't gotten around to do it, I will later on, in the after hours.
Distribution: Debian Sid AMD64, Raspbian Wheezy, various VMs
Posts: 7,680
Rep:
I'm glad IDJC was of some help and I would actually like to ask my own question here:
When you install IDJC does it install Jack also and, if so, does that mean that when you run IDJC it locks the sound server so no other programs have sound?
I ask because it is a while (a couple of years I think) since I used IDJC last and there were sound problems in Ubuntu relating to Pulse Audio at the time so I never did get it working with ALSA and still have other applications using sound.
I'm sounding like the newby I am here but I'm loath to install it in case ALSA is modified and I lose sound for my other applications.
I'm glad IDJC was of some help and I would actually like to ask my own question here:
When you install IDJC does it install Jack also and, if so, does that mean that when you run IDJC it locks the sound server so no other programs have sound?
I ask because it is a while (a couple of years I think) since I used IDJC last and there were sound problems in Ubuntu relating to Pulse Audio at the time so I never did get it working with ALSA and still have other applications using sound.
I'm sounding like the newby I am here but I'm loath to install it in case ALSA is modified and I lose sound for my other applications.
I may have good news for you:
1) Yes, Ubuntu installed jackd as a dependency. I hesitated a lot before accepting it because I also have had my share of problems with Jack. But I went ahead with it and it works this time! No problems at all.
2) I just launched Audacious then Mplayer with some other random song while streaming with icecast2/IDJC. I didn't have any problem. The computer across the room kept playing the stream while my notebook played the other (unrelated) song on Audacious or Mplayer. I hope that means there is no locking.
Distribution: Debian Sid AMD64, Raspbian Wheezy, various VMs
Posts: 7,680
Rep:
Thank you, much appreciated. I thought it would be fine or I would not have mentioned it -- I've a couple of sound cards on this PC so have to be more careful.
Understandable. As it turns out, it's not necessary for you to mess with either anymore. Later today, I'll post a patch file for ices-0.4. The patch creates a new "Type" and supporting "ExternalData" element in the config file.
In short, with the patch appied (and ices re-compiled), your config file can include these lines:
It's simple: the value of element "File" is the executable file. The value of "Type" is the flag that says ices should run an external program. The value of "ExternalData" can be anything you want. The idea is that your script/executable uses the ExternalData as a way to keep track of what songs to serve. In other words, you could write one script to serve multiple streams (e.g. alternative stream, jazz stream, classical stream, etc.), and the value of ExternalData is given to the program on the command line so that the program knows which stream it needs to work on.
There are three ways the executable will be called: (1) initialization, (2) get next song, and (3) shutdown. Each way will be distinguished by different command line arguments.
As an example, I just tested it with the following config file settings:
The script/executable can ignore all of the arguments; ices doesn't care. The only requirement is that the script/executable output the full path and filename for the next song. Bear in mind that ices will only read the first line of that output. Any output beyond the first line will be ignored.
Like I said, I'll post the patch later today along with instructions on how to apply it and any usage warnings (it's still a little rough).
My goal was simply to get support for an external executable. So, I have not done much testing. In other words, deviate from the examples at your own risk.
(1) Download the attachment or paste the above code into a file and save it (e.g. "ices_external.patch").
(2) Extract the ices-0.4 tar file and cd into the created source tree:
Code:
tar xvzf ices-0.4.tar.gz
cd ices-0.4
(3) Apply the patch:
Code:
patch -p1 < ../ices_external.patch
(4) Compile/install like normal:
Code:
./configure && make && make install
As mentioned in my earlier reply, the ices config file used should:
(5) Use the <File> element to provide the full path to your executable file
(6) Change the <Type> element to a value of "external"
(7) Add an <ExternalData> element with a value of whatever your executable wants/need to distinguish the stream. If you do not include an <ExternalData> element, ices will default to "--ices_id <seconds_since_epoch>"
Also, as stated earlier, there will be three types of calls: initialization, get-next, and shutdown.
Your executable does not need to respond to the initialization ("--ices_action init") or shutdown ("--ices_action shutdown") calls. In fact, any response will be ignored. So, your executable should not supply a filename for the "--ices_action init" argument or it will be ignored. The initialization and shutdown actions are provided as an aid to the executable for preparation/cleanup if necessary.
On get-next calls ("--ices_action getnext"), the executable should supply the full path to a song for streaming on one line. The ices program will read the first line only. Subsequent lines will be ignored.
I hope it's useful.
Note to moderators: I included the text of the patch in the reply itself on the off chance this thread goes to "archive" status some day and the attachment is no longer available. If including it both ways is a no-no, you have my apologies.
Last edited by Dark_Helmet; 01-15-2012 at 08:34 PM.
Hello. I'm back. Sorry for taking so long to reply. I have been super busy. But tonight I have the free time for that.
Wow, you have been busy. You wrote a patch. I am going to try it now, but first I tried to do without it. Yes, because I thought none of this would be necessary. Can anyone blame me? Look at this:
<param name='program'></param>
Name of a program or script to call. All this script should do is output a single line containing the filename to play, however the script itself can be arbitrarily complex. With a little ingenuity you could implement play frequencies, music genre depending on time of day and regularly placed trailers.
If you send ices a HUP signal, it will move to the next track in a playlist.
Doesn't it absolutely make it all sound like no patching is necessary, because all the functionality is already built in?
But alas, I can't make it work so I am finally going to try your patch. I will be back in a few minutes...
Yeah. I saw that documentation and immediately thought, "it's already been done." Then I looked a little closer at the source code when things didn't work. I'll just say that documentation is "out of date"--which is saying something because the tarball of ices-0.4 shows the last modification of contained files as being around 2004.
Anyway, it seems all of that <param name='blah'> was either ripped out or never implemented for 0.4. All that the stock 0.4 version can do is hook into Python/Perl.
Hum, the patch was applied and ices built without any errors (I think). But I can't make it work. I am reading your instructions again and again and the whole thing is a little bit confusing. First off, there are configuration "sections", to wit:
Where exactly do those lines go? I put them inside the <Playlist> tags, then outside, in both cases got many errors, so I decided to come here and get some more help...
No problem, I'll post a sample config. Those elements in my earlier post should be located in the <Playlist> group.
The following is only the <Playlist> portion of the config. I can post the whole thing if necessary.
Code:
<Playlist>
<!-- This is the filename used as a playlist when using the builtin
playlist handler. -->
<File>/home/username/temp/playlist_script.bash</File>
<!-- Set this to 0 if you don't want to randomize your playlist, and to
1 if you do. -->
<Randomize>1</Randomize>
<!-- One of builtin, perl, or python. -->
<Type>external</Type>
<ExternalData>--id testing</ExternalData>
<!-- Module name to pass to the playlist handler if using perl or python.
If you use the builtin playlist handler then this is ignored -->
<Module>ices</Module>
<!-- Set this to the number of seconds to crossfade between tracks.
Leave out or set to zero to disable crossfading (the default).
<Crossfade>5</Crossfade>
-->
</Playlist>
I'm not sure if the elements are case sensitive or not. I'd have to go back and check, but try them in mixed case on the off chance that you may have typed the element names in all lowercase.
If that still doesn't work, post the errors and I'll look into it more closely.
OK. Lots of progress here. Just one damn glitch I can't resolve. Not sure you will be able to help.
Here is the script I'm using. Even if you are not familiar with Tcl, you should be able to read it:
Code:
#!/usr/bin/env tclsh
# SET FILES - OPTIONS - CONFIG
set queuefile "/home/luc/ices/queue.txt"
set historyfile "/home/luc/ices/history.txt"
# Note about Tcl:
# [open $file r] = open for reading
# [open $file w] = open for writing
# [open $file a] = open for appending
# READ QUEUE FILE AND MAKE QUEUE LIST
set _fp [open $queuefile r]
set queuelist [string trim [read $_fp]]
set queuelist [split $queuelist "\n"]
close $_fp
# PICK FIRST SONG IN THE LIST AND ADD IT TO HISTORY
set playnow [lindex $queuelist 0]
set _fp [open $historyfile a]
puts $_fp $playnow
close $_fp
# BUILD NEW LIST WITH FIRST SONG REMOVED
# REWRITE/UPDATE QUEUE FILE
set queuelist [lrange $queuelist 1 end]
set _fp [open $queuefile w]
foreach i $queuelist {
puts $_fp $i
}
close $_fp
puts $playnow
exit
And here is a queue.txt file I made for testing:
Quote:
/media/music/TV themes/Get Smart.mp3
/media/music/P/Pixies/Surfer Rosa/01 - Bone Machine.mp3
/media/music/P/Pixies/Surfer Rosa/02 - Break My Body.mp3
/media/music/P/Pixies/Surfer Rosa/03 - Something Against You.mp3
So first I test it on the command line:
Code:
$ ./enqueue.tcl
Every time I run it, it prints the path to one song in the list, in the expected order. The queue.txt file ends up empty, as expected. The history file effectively becomes a list of songs that have already been played. So it works, right? Right?
Well, almost. I always get this output:
Quote:
luc[1205-1]/progs/ices/ices-0.4/src> ./ices -c /home/luc/ices/config.txt
Logfile opened
error writing "stdout": broken pipe
while executing
"puts $playnow"
(file "/home/luc/ices/enqueue.tcl" line 33)
Playing /media/music/P/Pixies/Surfer Rosa/01 - Bone Machine.mp3
Mounted on http://localhost:9000/ices
And thus the first song always gets skipped. If the queue file has only one song, the whole thing fails.
There is nothing wrong with that first, "Get Smart" MP3 file. It will play fine if moved to the end of the queue, or 2nd place etc. I have also tested with other files. It's always the first one that fails.
Apart from that glitch, the little machine works fine. It will play all the songs (except the first one) till the end of the list. I just have to find out why it always craps out on the first song.
And thus the first song always gets skipped. If the queue file has only one song, the whole thing fails
Quote:
Originally Posted by Dark_Helmet
Your executable does not need to respond to the initialization ("--ices_action init") or shutdown ("--ices_action shutdown") calls. In fact, any response will be ignored. So, your executable should not supply a filename for the "--ices_action init" argument or it will be ignored. The initialization and shutdown actions are provided as an aid to the executable for preparation/cleanup if necessary.
Ok, when ices runs, it first calls your script with an "--ices_action init" command line, subsequent calls use "--ices_action getnext", and a final call (when ices is killed) with "--ices_action shutdown".
The reason for this is in case the external executable needs to do any preparation. For instance, submit a SQL query to a database to get a list of songs, open a network connection to some other machine, etc. The ices program does not expect a response when it issues the "--ices_action init" nor the "--ices_action shutdown".
All you need to do is modify your TCL script to check if the "--ices_action init" arguments are present. If so, then exit without doing anything--likewise for the shutdown.
If it makes more sense to reverse it, then have the TCL script look for "--ices_action getnext" on the command line, and only then print the next song.
EDIT2:
A quick Google search told me that TCL accesses command line options with names similar to C. The number of arguments is stored in $argc and the individual command line arguments are stored in an array named $argv (and accessible with something like "[lindex $argv 0]" etc.)
EDIT:
To be honest, I don't know if TCL has a mechanism for examine the command line arguments, but I would be surprised if it doesn't. If TCL does not have such a mechanism, you can wrap your TCL script with something like this:
Code:
#!/bin/bash
while [ $# -gt 1 ] ; do
if [ \( "${1}" = "--ices_action" \) -a \( "${2}" = "getnext" \) ] ; then
/path/to/tcl/script.tcl
fi
shift
done
Then have ices call this wrapper script. The wrapper script will only invoke the TCL script when "--ices_action getnext" is present on the command line. Keep in mind though, this simple wrapper discards any extra information you would pass with the ExternalData.
Last edited by Dark_Helmet; 01-18-2012 at 01:36 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.