Hi, Romain.
Can you give an example of usage for these functions?
I've started an instance of liquidsoap:
*$ liquidsoap -t dynamic_playlist.liq 'output.dummy(blank())*'
Then connected via telnet:
*telnet localhost 1234*
and tried to add a playlist:
dynamic_playlist.start "~/pl.pls"
ERROR: Lang.Invalid_value(_, "Either name or mount must be defined")
END
dynamic_playlist.start (~/pl.pls)
ERROR: Lang.Invalid_value(_, "Either name or mount must be defined")
END
dynamic_playlist.start("/home/alius/pl.pls")
ERROR: Lang.Invalid_value(_, "Either name or mount must be defined")
On Fri, Mar 11, 2011 at 11:13 PM, Romain Beauxis <[email protected]>wrote:
> 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
> >
>
--
-------------------------------------------
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