Hey,
2011/3/11 Boris Zhidkov <[email protected]>:
> Hi.
>>
>> You may as well use a recent liquidsoap (SVN/hg) and dynamically
>>
>> create/destroy sources in your script. For instance, you can register
>>
>> a telnet/server command that creates a new source/output and a command
>>
>> that destroys that source.
>>
>> I can give more details about this if you are interested.
>
> Yes, I think it's an optimal way for me.
Cool :)
So first some outlines:
* It is not possible in a natural way to change a source currently
being streamed. it should be possible using source.dynamic but this is
still experimental and I'll let David comment on it. I will show a
hack to work around that tho.
* You need a recent liquidsoap, prob. at least beta1 but most likely SVN/hg
* The idea is to create a new output using a telnet command.
Now let's see one possible way to do it. In this example, we will
register a command that creates a playlist source using an uri passed
as argument and outputs it to a fixed icecast output.
With more work on parsing the argument passed to the telnet command,
you may create more evolved sources, such as the possibility to change
the output parameters etc..
Due to some limitations of the language, I have had to use some
intricate (but classic) functional programming tricks. I have
commented them in order to help reading the code..
8<-------------->8
# First, we create a list referencing the dynamic sources:
dyn_sources = ref []
# This is our icecast output.
# It is a partial function: the source needs to be given!
out = output.icecast(%mp3,
host="test",
password="hackme",
fallible=true)
# Now we write a function to create
# a playlist source and output it.
def create_playlist(uri) =
# The playlist source
s = playlist(uri)
# The output
output = out(s)
# Register output is the list of sources
dyn_sources :=
list.append( [(uri,output)],
!dyn_sources )
"Done!"
# PS: we need a x :: l syntactic sugar :)
end
# And a function to destroy a dynamic source
def destroy_playlist(uri) =
# We need to find the source in the list,
# remove it and destroy it. Currently, the language
# lacks some nice operators for that so we do it
# the functional way
# This function is executed on every item in the list
# of dynamic sources
def parse_list(ret, current_element) =
# ret is of the form: (matching_sources, remaining_sources)
# We extract those two:
matching_sources = fst(ret)
remaining_sources = snd(ret)
# current_element is of the form: ("uri", source) so we check the
first element
current_uri = fst(current_element)
if current_uri == uri then
# In this case, we add the source to the list of
# matched sources
(list.append( [snd(current_element)],
matching_sources), remaining_sources)
else
# In this case, we put the element in the list of remaining
# sources
(matching_sources,
list.append([current_element],
remaining_sources))
end
end
# Now we execute the function:
result = list.fold(parse_list, ([], []), !dyn_sources)
matching_sources = fst(result)
remaining_sources = snd(result)
# We store the remaining sources in dyn_sources
dyn_sources := remaining_sources
# If no source matched, we return an error
if list.length(matching_sources) == 0 then
"Error: no matching sources!"
else
# If more than one source matched, we return a warning
msg =
if list.length(matching_sources) > 1 then
"Warning: more than one source matched the given uri!\n"
else
""
end
# Now we stop all sources
list.iter(source.shutdown, matching_sources)
# And return
"#{msg}Done!"
end
# PS: we could use a universal type for list.assoc and a (x,y) implicit
# matching :)
end
# Now we register the telnet commands:
server.register(namespace="dynamic_playlist",
description="Start a new dynamic playlist.",
usage="start <uri>",
"start",
create_playlist)
server.register(namespace="dynamic_playlist",
description="Stop a dynamic playlist.",
usage="stop <uri>",
"stop",
destroy_playlist)
8<-------------->8
Now, if you execute this code (add a output.dummy(blank()) if you have
no other output..), you have two new telnet commands:
* dynamic_playlist.start <uri>
* dynamic_playlist.stop <uri>
which you can use to create/destroy dynamically your sources.
With more tweaking, you should be able to adapt these ideas to your
precise needs.
If you want to plug those sources into an existing output, you may
want to use an input.harbor in the main output and change the
output.icecast in the dynamic source creation to send everything to
this input.harbor. You can use the %wav format in this case to avoid
compressing/decompressing the data..
Hope this inspires you, let us know if you have more tricks using this :)
(And I should really put that in the doc :))
Romain
> On Fri, Mar 11, 2011 at 1:33 AM, Romain Beauxis <[email protected]>
> wrote:
>>
>> Hi Boris!
>>
>> Le 10 mars 2011 13:15, Boris Zhidkov <[email protected]> a écrit :
>> > Hi, all.
>> > I want to manage streams dynamically, so I need to generate .liq scripts
>> > and
>> > execute them in some way.
>> > How can I realize it?
>> > Is it possible to run liquidsoap scripts via telnet? Or must I replace
>> > scripts in /etc/liquidsoap and restart init.d/liquidsoap everytime I
>> > generate new scripts?
>>
>> You have many possible ways.
>> The simplier is to generate .liq scripts in /etc/liquidsoap and
>> start/stop them using init.d. However, current init script starts/stop
>> all scripts I believe..
>>
>> You may as well use a recent liquidsoap (SVN/hg) and dynamically
>> create/destroy sources in your script. For instance, you can register
>> a telnet/server command that creates a new source/output and a command
>> that destroys that source.
>> I can give more details about this if you are interested.
>>
>> Romain
>>
>>
>> > ---------------------------
>> > Thanks, Boris Zhidkov
>> >
>> >
>> > ------------------------------------------------------------------------------
>> > Colocation vs. Managed Hosting
>> > A question and answer guide to determining the best fit
>> > for your organization - today and in the future.
>> > http://p.sf.net/sfu/internap-sfd2d
>> > _______________________________________________
>> > Savonet-users mailing list
>> > [email protected]
>> > https://lists.sourceforge.net/lists/listinfo/savonet-users
>> >
>> >
>
>
>
> --
> -------------------------------------------
> WBR, Boris Zhidkov
>
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Savonet-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-users