Hi All,
I am using LiquidSoap to build an ad insertion system for different regions
whereby:
1. Main programme comes in via RTP (input.gstreamer).
2. Two regions: region_one - main feed from the playout system - contains
ads for that region already) and region_two, has a process that connects to
LiquidSoap that adds items to the queue (ads_region_two).
The configuration looks a bit like this:
---
set("server.telnet",true)
set("server.telnet.bind_addr","0.0.0.0")
set("server.telnet.port",1234)
set("server.telnet.reverse_dns",false)
requests_region_one = mean(request.equeue(id="ads_region_one"))
requests_region_two = mean(request.equeue(id="ads_region_two"))
stream = mksafe(input.gstreamer.audio(pipeline='udpsrc port=5004
caps="application/x-rtp, media=(string)audio, clock-rate=(int)48000,
format=(string)S16BE, channels=(int)2, payload=(int)96" ! queue !
rtpL16depay', max=0.2))
#Make sure the buffer is empty when we transition - we want the audio on
return to be live
output.dummy(stream)
def crossfade_ad_out(a,b)
add(normalize=false,
[ sequence(merge=true,
[fade.initial(duration=.3,b) ])])
end
def crossfade_ad_in(a,b)
add(normalize=false,
[ sequence(merge=true, [b]) ])
end
region_one_source = fallback(track_sensitive=false,
transitions=[crossfade_ad_in, crossfade_ad_out],
[crossfade(start_next=0.1,fade_out=0.,fade_in=0.,requests_region_one),
stream])
#Just doing this so that the chains are the same and have the same latency
region_two_source = fallback(track_sensitive=false,[requests_region_two,
stream])
#IceCast Local
output.icecast(%mp3(stereo=false, bitrate=96,samplerate=32000),
host = "127.0.0.1", port = 8000,
public=false,
password = "<snip>", mount = "region_one_mp3",
region_one_source)
output.icecast(%aacplus(channels=1,bitrate=24,samplerate=44100),
host = "127.0.0.1", port = 8000,
public=false,
password = "<snip>", mount = "region_one_aac",
region_one_source)
output.icecast(%mp3(stereo=false, bitrate=96,samplerate=32000),
host = "127.0.0.1", port = 8000,
public=false,
password = "<snip>", mount = "region_two_mp3",
region_two_source)
output.icecast(%aacplus(channels=1,bitrate=24,samplerate=44100),
host = "127.0.0.1", port = 8000,
public=false,
password = "<snip>", mount = "region_two_aac",
region_two_source)
#Region One output to RTP
output.gstreamer.audio(pipeline='audioconvert ! audioresample ! rtpL16pay
pt=10 ! application/x-rtp, clock-rate=48000, channels=2, format=S16LE !
udpsink host=127.0.0.1 port=6001 async=true', region_one_source)
#Region Two output to RTP
output.gstreamer.audio(pipeline='audioconvert ! audioresample ! rtpL16pay
pt=10 ! application/x-rtp, clock-rate=48000, channels=2, format=S16LE !
udpsink host=127.0.0.1 port=6002 async=true', region_two_source)
#Output to logger
output.file(
%mp3(stereo=false, bitrate=64,samplerate=22050),
"/var/audio_logger/%Y/%m/%d/region_one-%Y-%m-%d-%H00.mp3",
reopen_when={0m0s},
region_one_source
)
output.file(
%mp3(stereo=false, bitrate=64,samplerate=22050),
"/var/audio_logger/%Y/%m/%d/region_two-%Y-%m-%d-%H00.mp3",
reopen_when={0m0s},
region_two_source
)
---
In this configuration, it's extremely important that there is consistent
(fixed) latency between audio coming in from the input (stream =
mksafe(input.gstreamer.audio() ) and the audio that comes in from the
queue. This is to ensure seamless insertion of ads with minimal artefacts
as a result of coming in too early/late.
I can fine tune the latency between receiving the signal to insert ads and
when the queue is populated with ads and this works really well initially.
What I am trying to address however is that over time, there appears to be
some drift resulting in more delay and hence ad insertions are occurring
late.
I'm wondering if this is where I should be looking at using a single clock
to keep this all in sync?
Many thanks!
Jonathan
------------------------------------------------------------------------------
_______________________________________________
Savonet-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-users