Hi!
Thanks. I haven't noticed. Now it works.
But I have another question: I need to set a mount when adding playlists.
But server.register takes one argument only.
On Sun, Mar 13, 2011 at 1:13 AM, Romain Beauxis <[email protected]>wrote:
> 2011/3/12 Boris Zhidkov <[email protected]>:
> > Hi, Romain.
>
> Hi!
>
> > 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")
>
> Some of the arguments for output.icecast are not defined. you need to
> add at least the mountpoint:
> out = output.icecast(%mp3, host="foo", password="bar",
> mount="bla.mp3", fallible=true)
> You may as well use an output to the local soundcard to test locally:
> out = output.ao(fallible=true)
>
> Also, you use the command this way:
> dynamic_playlist.start /home/alius/pl.pls
> (no double quotes/quotes..)
>
> Romain
>
> > 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
> >
>
--
-------------------------------------------
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