ОсновноеRadiotalkПользовательское
Технологии вещания, софт, скрипты
6   •   Посмотреть все темы

liquidsoap

 

382
Grigorij @gyurgin_1
second8prize пишет:

Или хотя бы когда он начался?

Может быть metadata update у icecast запросить проще (это ведь и есть старт трека)?
Делаем xsl файлик <xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" >
<xsl:output omit-xml-declaration="yes" method="text" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" indent="no" encoding="UTF-8" /><xsl:strip-space elements="*"/>
<xsl:template match = "/icestats" >
<xsl:for-each select="source">
<xsl:value-of select="metadata_updated" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
, пихаем его в web root айскаста и опрашиваем.

3
second8prize @second8prize
По совету tarasian666 поднял telnet сервер у liquidsoap.

На этой же машине установил http + php.

Написал скрипт, который отправляет запросы telnet (<mountpoint>.remaining и <mountpoint>.metadata) и возвращает примерно вот что:


Time: 211.42
2014/02/13 17:28:08 => Amon DГјГјl II - Good bye my love
2014/02/13 17:23:22 => The Walkmen - Save The Last Dance For Me (feat. Ian Svenonius)
2014/02/13 17:17:37 => Moderat - Therapy
2014/02/13 17:13:08 => The Black Ryder - To Never Know You
2014/02/13 17:08:59 => Wolfmother - 10,000 Feet
2014/02/13 17:06:24 => Tinkerbell's Fairydust - In My Magic Garden [12/1967]
2014/02/13 17:03:00 => Polvo - Lantern
2014/02/13 16:59:16 => Truckfighters - Loose
2014/02/13 16:55:09 => Mercury Rev - Vermillion
2014/02/13 16:52:03 => The Black Box Revelation - 5 O'Clock Turn Back The Time


При первом обращении к web-странице Аякс асинхронно вызывает скрипт, считывает интервал времени до конца текущего трека и вставляет на нее полученную информацию. Следующий раз вызов скрипта происходит через время, полученное в первом обращении.

Отредактировано second8prize - 13.02.2014
7094
Dim @Render
Falcon пишет:

Добрый день. Такой вопрос:
Есть два инпута, их надо смикшировать. У первого инпута понизить громкость до 20%, и на него наложить второй инпут со 100% громкостью. Желательно сделать "врезку" красивым кроссфейдом.
Подскажите, как сие можно реализовать?
Читал про функцию smooth_add(~delay=0.5,~p=0.2,~normal,~special), но не уверен, что она подойдет.
Спасибо.

Функция есть в коробке.
Её можно не объявлять по идее, а просто использовать к примеру:
radio = smooth_add(normal=radio,special=switch([({ 5m0s or 15m0s or 30m0s }, promo)]))

У меня же попутный вопрос, касаемо smooth_add.

def smooth_add(~delay=0.5,~p=0.2,~normal,~special)
d = delay
fade.final = fade.final(duration=d*2.)
fade.initial = fade.initial(duration=d*2.)
q = 1. - p
c = amplify
fallback(track_sensitive=false,
[special,normal],
transitions=[
fun(normal,special)->
add(normalize=false,
[c(p,normal),
c(q,fade.final(type="sin",normal)),
sequence([blank(duration=d),c(q,special)])]),
fun(special,normal)->
add(normalize=false,
[c(p,normal),
c(q,fade.initial(type="sin",normal))])
])
end

Можно видоизменять данную функцию, её дефолтные параметры фейда и выполнения.
Так вот. По дефолту наложение происходит таким образом, что основной играемый звук, притухает, затем воспроизводится наложение и звук возвращается в исходное положение.
Отвечает за уровень наложения - p=0.2
Чем ниже значение, тем громче наложение и тише основной сорс.

В моём случае пытаюсь добиться того, чтобы основной звук не притухал, а поверх накладывался джингл с полным звуком, без всяких фейдов.
В итоге если снижать значение p=0.2 - джингл становится громче, основной звук - тише. Повышать - джингл не слышно.
Среднее 0.5 - то же не то.

Получается только так достичь результата:
def smooth_add(~delay=0.1,~p=0.5,~normal,~special)
d = delay
fade.final = fade.final(duration=d*2.)
fade.initial = fade.initial(duration=d*2.)
#q = 1. - p
c = amplify
fallback(track_sensitive=false,
[special,normal],
transitions=[
fun(normal,special)->
add(normalize=false,
[c(1.,normal),
c(1.,fade.final(type="sin",normal)),
sequence([blank(duration=d),c(1.,special)])]),
fun(special,normal)->
add(normalize=false,
[c(p,normal),
c(1.,fade.initial(type="sin",normal))])
])
end

Более менее работает, как нужно, но выходит неприятность спустя несколько часов.
Когда проходит 3-6 часов вещания с момента запуска, основной звук начинает "хрипеть", то есть его уровень явно выходит за первоначальный постепенно. Таким образом чем далее, тем слушать уже не возможно...

Может кто в курсе, как правильно поправить функцию? Как с ней уже только не мучился.
Синтаксис этой функции в полной мере так пока и не удалось побороть... :(

1
tazman_555 @tazman_555
Привет! Кто подскажет как в эту конструкцию включить харбор, все перелопатил вдоль и поперек этой темы, ну не получается((
#!/usr/bin/liquidsoap

set("log.file.path","/var/data/test.log")
set("log.level",3)

# Загрузка плейлиста 1
myplaylist = mksafe(playlist(reload=3000, '/var/data/music'))

# Загрузка джинглов
jingles = mksafe(playlist("/var/data/promo"))

radio = myplaylist

radio = rotate(weights = [1, 4],[jingles, radio])

# включение telnet-сервера
set("server.telnet.bind_addr","127.0.0.1")
set("server.telnet.port",1231)
set("server.telnet",true)

# Пропускать тишину во всех плейлистах
# Cut blanks (bonus-tracks)
s = skip_blank(length=5.)

# Настройка crossfade
# radio = normalize( radio )
radio = smart_crossfade(start_next=2.0,fade_out=3.0,fade_in=3.0,radio)

# Запуск основного потока mp3
output.icecast(%mp3,description = "MP3",
host = "localhost", port = 80,
password = "PASSWD", mount = "test", radio,
name = "NAME", url = "http://site.com", genre = "GENRE",)

И еще вопрос, что и куда надо писать в конфиге, что бы request.push, т.е. управление очередью через telnet работало?
Спасибо)

Отредактировано tazman_555 - 18.02.2014
7094
Dim @Render
Никто не сталкивался с такой проблемой?
Когда используется switch для ротации source плейлистов, не срабатывает включение джинглов после определенного количества треков.
radio = rotate(weights = [1, 4],[jingles, radio])
То есть, имеем следующее:
# source плейлисты
general_list = smart_crossfade(start_next=3.,fade_out=2.3,fade_in=0.7, playlist(reload=3600,"~/GEN"))
ps_list = smart_crossfade(start_next=5.,fade_in=6.,fade_out=3., conservative=false, high=-28., medium=-48., mksafe(input.http("http://trololo.ru/stream")))
....
...
mix_list = smart_crossfade(start_next=3.,fade_out=2.3,fade_in=0.7, playlist(reload=3600,"~/MIX"))
relax_list = smart_crossfade(start_next=3.,fade_out=2.3,fade_in=0.7, playlist(reload=3600,"~/RELAX"))
jingle_list = playlist(reload=600,mode="random","~/jingles")

general = rotate(weights = [1, 4],[jingle_list, general_list])

#расписание эфира первое - высший приоритет
default = switch(track_sensitive=false,
[
({ (2w) and 0h - 1h }, ps_list),
({ 7h - 8h or 12h -13h }, mix_list),
...
......
({ 0h - 1h or 2h - 7h or 8h - 12h or 13h - 17h or 18h - 23h }, general),
({ true }, general)
])

.... далее используется crossfade и mksafe которые так же пробовал убирать, не помогло
..


Треки играют одни за одним, джинглы - нет.
rotate, random - одно и тоже. Причём при запуске мыла, первым играет джингл, но дальше после опр.количества треков - нет.
Ещё интересный момент. Если через telnet дать команду [mount].skip - при смене треков, может включиться джингл...

9
den68 @den68
господа, не уловил с чего, но пропало динамическое обновление meta даты.
может кто сталкивался?
meta берется динамически:


def rewrite_dynamic_metadata(pls,lab) =
content = list.hd(get_process_lines("/Clients/WWW/exec/radio/radio_title.php #{lab}"))
log("--- Add META dynamic: #{content}")
rewrite_metadata([
("artist",meta_artist),
("title", "#{meta_title1} #{content} #{meta_title2}" ),
("comment",meta_comment)
],pls)
end


в описании источника стоит последним:


iplaylist = rewrite_dynamic_metadata(iplaylist,"vinterview")


далее ротация...


zplaylist = fallback(track_sensitive=false, transitions=[trans1,trans1],[
fallback(track_sensitive=true,[
iplaylist,
normalize(aplaylist)
]),
normalize(mplaylist)
])
.... итд


trans1 по факту для этого источника вызывает xfade:


def xfade(a,b)
add(normalize=false,
[ sequence([ blank(duration=1.),
fade.initial(duration=2.,b) ]),
fade.final(duration=2.,a) ])
end


по сути это все преобразования на этапе смены источника с динамической meta датой.
проставил дату с временем на meta title в скрипте, так он его читает только при старте, далее обращений за meta нет.
чего случилось, ума не приложу, помогите советом.

6245
Тарас @tarasian666

iplaylist = rewrite_dynamic_metadata(iplaylist,"vinterview")

здесь нет даже намека на динамичность

9
den68 @den68
tarasian666 пишет:


iplaylist = rewrite_dynamic_metadata(iplaylist,"vinterview")

здесь нет даже намека на динамичность


ok, раньше как-то работало :)
а как ему намекнуть что оно динамическое?

вот собственно все формирование iplaylist:


iplaylist = delay(5.,input.external(samplerate=7800,restart=true,restart_on_error=true,"/Clients/WWW/exec/radio/radio_stream.php"))
iplaylist = filter(freq=2200.,q=0.7,mode="low",iplaylist)
iplaylist = filter(freq=10.,q=0.8,mode="high",iplaylist)
iplaylist = audio_to_stereo(iplaylist)
iplaylist = amplify(osc.float("/seek3",3.),iplaylist)
iplaylist = rewrite_dynamic_metadata(iplaylist,"vinterview")


на мой взгляд, он по контенту сам определяет и берет что характерно, стрмы из листа...
от туда PCM поток...

Отредактировано den68 - 28.03.2014
6245
Тарас @tarasian666
Надо привязать к какомо-то событию, например к смене трэка, не помню какие там есть, вроде on_track

9
den68 @den68
попробовал вставить пустышку on_track, да, действительно, в логах при смене траков есть обращения - спасибо!

но не могу сообразить, как правильно параметры функции через on_track передать:
хочется чего-то таково, но так не работает:


source = on_track(rewrite_dynamic_metadata_01(source,"string"),source)


но он принципиально передает функции, (ИМХО), только метадату, судя по мануалу, как правильно в таком случае передать остальные параметры?
работает только так, может я в синтаксисе чего не так понимаю ?


def rewrite_dynamic_metadata_01(m) =
log("--- Callback is empty #{m}")
end


а хотелось-бы по смыслу так:


def rewrite_dynamic_metadata_01(m,source,string) =
.....
end

Отредактировано den68 - 28.03.2014
7094
Dim @Render
def ab_played(t, m) =
log("Played. Done.")
system("uptime")
end

radio = on_end(ab_played, radio, delay=3.0)

9
den68 @den68
Render пишет:

def ab_played(t, m) =
...
radio = on_end(ab_played, radio, delay=3.0)


пример не в тему, к сожалению...
как из этой функции (ab_played) вызвать map_metadata(...,source) - вот основная проблема, как туда метку "string" и тип "source" передать?

или придется велосипед с флагами придумывать?
выставлять значение, в циклах читать значение, если совпадает, чего-то запускать, но опять возникает проблемы с типом source, как-то он плохо в произвольные функции передается... или я не умею его готовить.. ;)

Отредактировано den68 - 29.03.2014
68
Алексей @features
Подскажите, как научить liquidsoap воспринимать ссылки на файлы?

И ещё вопрос.
При отключении liquidsoap у меня отключается icecast. Не важно как, через rc.d скрипт или просто kill pid. Если liquidsoap вырубился, то icecast за ним следом. ОС Freebsd, icecast 2.3.3-kh10, liquidsoap 1.1.1+scm. Как собственно это починить?

upd: второй воспрос думаю отпадает. Косяк у icecast. Вот в логах что:
[2014-04-02 06:13:44] EROR thread/rwlock unlock error triggered at 0x28c3d3b8, source.c:317 (1)

Отредактировано features - 02.04.2014
398
ubuntu-studio @ubuntu-studio
features пишет:

upd: второй воспрос думаю отпадает. Косяк у icecast. Вот в логах что:
[2014-04-02 06:13:44] EROR thread/rwlock unlock error triggered at 0x28c3d3b8, source.c:317 (1)


У меня такой косяк был на FreeBSD с айсом установленным из портов, после отсоединения источника он падал.
Проблема решилась удалением и компиляцией из сайта icecast-kh

68
Алексей @features
ubuntu-studio пишет:

features пишет:

upd: второй воспрос думаю отпадает. Косяк у icecast. Вот в логах что:
[2014-04-02 06:13:44] EROR thread/rwlock unlock error triggered at 0x28c3d3b8, source.c:317 (1)


У меня такой косяк был на FreeBSD с айсом установленным из портов, после отсоединения источника он падал.
Проблема решилась удалением и компиляцией из сайта icecast-kh

Да, freebsd и icecast из портов. Возможно фикс в порты не внесли. Спасибо, буду его из сорцов ставить.

9
den68 @den68
Подскажите, как бороться с id источника?
после любых пертубаций (fallback,switch,strip_blank итд) оно меняется внизу пример лога...
а хотелось чтобы id весь путь источника было одним и тем-же, иначе чего хочется не отловить толком...
ситуацию с source.id(b) == source.id("ид источника") не предлагать - работает неправильно, по тому как ИМХО смотрим выше, ид меняется на последнюю операцию с уникальным числом...

может глобальные команды какие на эту тему есть? гугл ничего не дал...


2014/04/06 08:59:09 [lang:1] ---- Transition blognews: = a: empty_9211 b: blognews
2014/04/06 09:00:11 [lang:1] ---- Transition else: = a: empty_9222 b: strip_blank_8817
2014/04/06 09:00:11 [lang:1] ---- Transition else: = a: empty_9241 b: switch_8816
2014/04/06 10:00:00 [lang:1] ---- Transition else: = a: empty_9260 b: quota_8833
2014/04/06 10:00:02 [lang:1] ---- Transition else: = a: map_metadata_8751 b: quota_8812
2014/04/06 10:00:42 [lang:1] ---- Transition else: = a: empty_9295 b: blogin
2014/04/06 10:00:42 [lang:1] ---- Transition else: = a: empty_9314 b: strip_blank_8819
2014/04/06 10:00:43 [lang:1] ---- Transition else: = a: empty_9333 b: strip_blank_8820
2014/04/06 10:00:45 [lang:1] ---- Transition blognews: = a: empty_9352 b: blognews
2014/04/06 10:01:47 [lang:1] ---- Transition else: = a: empty_9363 b: strip_blank_8817
2014/04/06 10:02:05 [lang:1] ---- Transition else: = a: empty_9382 b: speechblog
2014/04/06 10:02:06 [lang:1] ---- Transition else: = a: empty_9401 b: strip_blank_8819
2014/04/06 10:02:07 [lang:1] ---- Transition else: = a: empty_9420 b: strip_blank_8820
2014/04/06 10:02:44 [lang:1] ---- Transition else: = a: empty_9439 b: blogin
2014/04/06 10:02:44 [lang:1] ---- Transition else: = a: empty_9458 b: strip_blank_8817
2014/04/06 10:02:57 [lang:1] ---- Transition else: = a: empty_9477 b: map_metadata_8751
2014/04/06 10:02:58 [lang:1] ---- Transition else: = a: empty_9496 b: strip_blank_8819
2014/04/06 10:02:59 [lang:1] ---- Transition else: = a: empty_9515 b: strip_blank_8820
2014/04/06 10:03:00 [lang:1] ---- Transition else: = a: map_metadata_8751 b: quota_8812


9
den68 @den68
и еще вопрос, как средствами сабжа проиграть только один файл из плей листа.
фалбек не предлагать, поскольку если из листа1 надо проиграть 1 файл, то из остальных источников, а их 4 надо брать с учетом track_sensitive=true, rotate на практике тоже мало подходит ... или я не умею его готовить ...

131
Enzo @enzO
Kak izpravit stob v icecast status pokazival ,( Currently playing: ) nepokazivait nazvania pesni , esli ve6ayu v mp3 formate vso ok pokazivait no esli aac+ ili opus to tam pustata:(

p.s. icecast samiy novij i liquidsoap toza.

Отредактировано enzO - 07.04.2014
8
Саша @Sasha_Yohan
а можно как то обновить конфиг не выключая liquidsoap?
по типу как kill -hup в icecast
чтобы радио не выключать и снова включать

6245
Тарас @tarasian666
никак, но есть много методов как сделать это ненужным, так как много чем можно управлять