Quite a lot on HabrΓ© said about Internet broadcasting from the inside. There are even well-written theoretical foundations of Internet broadcasting, which I advise you to read. In this article I would like to talk about the organization of another amateur Internet radio station, built on a bundle of undeservedly little-known Liquidsoap 1.0.1 and the omnipresent IceCast 2.3.2 . The article is designed for those who at least approximately know what an audio stream is, IceCast, the Linux console, and what he wants to get. However, it was written by a novice user, so my decision does not even bail at the title of optimal.# zypper in icecast <icecast> <limits> <clients>100</clients> <sources>2</sources> <threadpool>5</threadpool> <queue-size>524288</queue-size> <client-timeout>30</client-timeout> <header-timeout>15</header-timeout> <source-timeout>10</source-timeout> <burst-on-connect>1</burst-on-connect> <burst-size>65535</burst-size> </limits> <authentication> <source-password>mypass</source-password> <relay-password>mysecondpass</relay-password> <admin-user>adminuser</admin-user> <admin-password>mythirdpass</admin-password> </authentication> <hostname>localhost</hostname> <listen-socket> <port>8000</port> </listen-socket> <fileserve>1</fileserve> #_____________________________________________________________ # . , , . ices secure. <mount> <mount-name>/secure</mount-name> <hidden>1</hidden> # - <charset>UTF8</charset> # </mount> # mount' <mount> <fallback-mount>/secure</fallback-mount> # , <fallback-override>1</fallback-override> # <fallback-when-full>1</fallback-when-full> # , <mount-name>/HabraRadio_192</mount-name> # mount'. <charset>UTF8</charset> # </mount> <mount> <fallback-mount>/secure</fallback-mount> <fallback-override>1</fallback-override> <fallback-when-full>1</fallback-when-full> <mount-name>/HabraRadio_320</mount-name> <charset>UTF8</charset> </mount> <mount> <fallback-mount>/secure</fallback-mount> <fallback-override>1</fallback-override> <fallback-when-full>1</fallback-when-full> <mount-name>/HabraRadio_vorbis_avg_128</mount-name> <charset>UTF8</charset> </mount> #_____________________________________________________________ <paths> <basedir>/usr/share/icecast</basedir> <logdir>/var/log/icecast</logdir> <webroot>/usr/share/icecast/web</webroot> <adminroot>/usr/share/icecast/admin</adminroot> <alias source="/" dest="/status.xsl"/> </paths> <logging> <accesslog>access.log</accesslog> <errorlog>error.log</errorlog> <loglevel>3</loglevel> <logsize>10000</logsize> </logging> <security> <chroot>0</chroot> <changeowner> <user>icecast</user> <group>icecast</group> </changeowner> </security> </icecast> $ git clone https://github.com/savonet/liquidsoap-full.git liquidsoap $ cd liquidsoap $ make init $ cp PACKAGES.minimal PACKAGES # zypper in make autoconf automake ocaml libao-devel libmad-devel libmp3lame-devel flac-devel libgavl-devel ocaml-camomile-devel ocaml-camlimages-devel ocaml-camomile-data libtheora-devel ocaml-findlib-devel libsamplerate-devel libtag-devel libvorbis-devel gcc-c++ ocaml-pcre-devel libtiff-devel libjpeg62-devel libXpm-devel $ ./bootstrap $ ./configure --with-user=user --with-group=users $ make # make install radio βββ collection | β βββ efir | β β βββ daytime | β β β βββ jingles | , β β β βββ music | , β β βββ evening | , β β β βββ jingles β β β βββ music β β βββ morning | β β β βββ jingles β β β βββ music β β βββ night | β β βββ jingles β β βββ music β βββ programs β β βββ 1_prog | 1 β β βββ 2_prog | 2 β βββ promo | β βββ security | βββ technical | , βββ | #!/usr/local/bin/liquidsoap # # out = output.icecast( # icecast host = "127.0.0.1", # port = 8000, # user = "source", # password = "mypass", # name = "-", # genre = "Rock", # url = "http://habrahabr.ru", # encoding = "UTF-8" ) # telnet- set("server.telnet.bind_addr","127.0.0.1") set("server.telnet",true) # _____________________________________ # . # , , , . , . # wd = "/home/user/radio" # pl = "#{wd}/collection" # tech = "#{wd}/technical" # set("log.file.path","#{tech}/liquidsoap.log") # set("log.level", 3) # # promo_dir = "#{pl}/promo" # progr_dir = "#{pl}/programs" # ef = "#{pl}/efir" # ni = "#{ef}/night" mo = "#{ef}/morning" da = "#{ef}/daytime" ev = "#{ef}/evening" # mus_ni_dir = "#{ni}/music" mus_mo_dir = "#{mo}/music" mus_da_dir = "#{da}/music" mus_ev_dir = "#{ev}/music" # jin_ni_dir = "#{ni}/jingles" jin_mo_dir = "#{mo}/jingles" jin_da_dir = "#{da}/jingles" jin_ev_dir = "#{ev}/jingles" # . - , - . 1_prog_pl = "#{progr_dir}/1_prog.pl" 2_prog_pl = "#{progr_dir}/2_prog.pl" # _____________________________________ # "source", . # "reload" 360 , . # , , <code>mode = "normal"</code> . # , , , mus_ni = playlist (reload = 360, "#{mus_ni_dir}") mus_mo = playlist (reload = 360, "#{mus_mo_dir}") mus_da = playlist (reload = 360, "#{mus_da_dir}") mus_ev = playlist (reload = 360, "#{mus_ev_dir}") jin_ni = playlist (reload = 360, "#{jin_ni_dir}") jin_mo = playlist (reload = 360, "#{jin_mo_dir}") jin_da = playlist (reload = 360, "#{jin_da_dir}") jin_ev = playlist (reload = 360, "#{jin_ev_dir}") promo = playlist (reload = 360, "#{promo_dir}") 1_prog = playlist (reload = 360, "#{1_prog_pl}", mode = "normal") 2_prog = playlist (reload = 360, "#{2_prog_pl}", mode = "normal") # _____________________________________ # 4 , # ins_ni = rotate (weights = [2, 1], [jin_ni, promo]) ins_mo = rotate (weights = [2, 1], [jin_mo, promo]) ins_da = rotate (weights = [2, 1], [jin_da, promo]) ins_ev = rotate (weights = [2, 1], [jin_ev, promo]) # ni = rotate (weights = [3, 1], [mus_ni, ins_ni]) mo = rotate (weights = [3, 1], [mus_mo, ins_mo]) da = rotate (weights = [3, 1], [mus_da, ins_da]) ev = rotate (weights = [3, 1], [mus_ev, ins_ev]) #_______________________________________________________________________ # radio = switch (track_sensitive = true, [ ({ (1w21h - 1w22h) or (3w21h - 3w22h) or (5w21h - 5w22h)}, 1_prog), ({ (1w18h - 1w19h) or (3w18h - 3w19h) or (4w18h - 4w19h) or (5w18h - 5w19h)}, 2_prog), ({ 2h - 6h }, ni), ({ 6h - 9h }, mo), ({ 9h - 19h }, da), ({ 19h - 2h }, ev) ]) #_______________________________________________________________________ # crossfade radio = crossfade(start_next=1., fade_out=1., fade_in=1., radio) # , , out( %vorbis.abr(samplerate = 44100, channels = 2, bitrate = 128, max_bitrate = 192, min_bitrate = 96), description = "Average vorbis 96-128-192 Kbps", mount = "HabraRadio_vorbis_avg_128", mksafe(radio) ) out( %mp3(bitrate = 320, id3v2 = true), description = "MP3 320 Kbps", mount = "HabraRadio_320", mksafe(radio) ) out( %mp3(bitrate = 192, id3v2 = true), description = "MP3 192 Kbps", mount = "HabraRadio_192", mksafe(radio) ) wd = "/home/user/radio" pl = "#{wd}/collection" ef = "#{pl}/efir" ni = "#{ef}/night" mus_ni_dir = "#{ni}/music" mus_ni = playlist (reload = 360, "#{mus_ni_dir}") mus_ni = playlist (reload = 360, "/home/user/radio/collection/efir/night/music") ins_ni = rotate (weights = [2, 1], [jin_ni, promo]) ni = rotate (weights = [3, 1], [mus_ni, ins_ni]) rotate() - allows you to adjust the queueweights = [2, 1], [jin_ni, promo] - indicates to take 2 tracks from jin_ni, then 1 from the promo, after again 2 tracks from jin_ni and so on.weights = [3, 1], [mus_ni, ins_ni] - indicates to take 3 tracks from mus_ni, then 1 track from that already mixed playlist, which turned out to be a line earlier (ins_ni). radio = switch (track_sensitive = true, [ ({ (1w21h - 1w22h) or (3w21h - 3w22h) or (5w21h - 5w22h)}, 1_prog), ({ (1w18h - 1w19h) or (3w18h - 3w19h) or (4w18h - 4w19h) or (5w18h - 5w19h)}, 2_prog), ({ 2h - 6h }, ni), ({ 6h - 9h }, mo), ({ 9h - 19h }, da), ({ 19h - 2h }, ev) ]) switch() - switches audio sources at a specified time.track_sensitive = true - allows you to not interrupt the current track, even if the active playlist has timed out. Those. if the night track started at 05:59, then until it ends, the morning playlist will not take effect.({ (1w21h - 1w22h) or (3w21h - 3w22h) or (5w21h - 5w22h)}, 1_prog), - on Mondays, Wednesdays and Fridays from 21 to 22 hours to play the source 1_prog. #!/usr/bin/env python2 # -*- coding: utf-8 -*- import os import random finalPaylist = '/home/user/radio/collection/programs/1_prog.pl' music = '/home/user/radio/collection/efir/evening/music/' show = '/home/user/radio/collection/programs/1_prog/' myShow = sorted(os.listdir(show)) myMusic = os.listdir(music) listOfTracks = [] def getRandomTrack(list): i = 0 buf = random.choice(myMusic) while (buf in list) & (not i == 100): i += 1 buf = random.choice(myMusic) return buf for i in range(60): if not i%2: try: listOfTracks.append(show + myShow[i/2]) except : listOfTracks.append(music + getRandomTrack(listOfTracks)) else: listOfTracks.append(music + getRandomTrack(listOfTracks)) myFile = open(finalPaylist, 'w') for i in range(len(listOfTracks)): myFile.write(listOfTracks[i]+'\n') 0 19 * * * /home/user/radio/technical/generatorProg1.py 0 16 * * * /home/user/radio/technical/generatorProg2.py #!/bin/sh cp /home/user/radio/technical/liquidsoap.log /home/user/radio/technical/liquidsoap_backup.log cat /dev/null > /home/user/radio/technical/liquidsoap.log liquidsoap /home/user/radio/technical/start_liquidsoap /etc/init.d/icecast start chkconfig --add icecast radio = mksafe(radio) Source: https://habr.com/ru/post/156591/
All Articles