Seite 2 von 2 ErsteErste 12
Ergebnis 26 bis 42 von 42

Thema: VLC Stream Aufzeichnen und zwar Zeitgesteuert

  1. #26
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    ne ich mein der ist schon drin aber ist viel zu hoch? mit "60" betitelt es doch in Sekunden und nicht millisekunden?!

    MfG

  2. #27

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Zitat Zitat von DukeMan999 Beitrag anzeigen
    ...mit "60" betitelt es doch in Sekunden und nicht millisekunden?!
    In der allgemeine Doku steht es nicht drin, ich bin aber davon ausgegangen das es sich um Sekunden handelt.. aber hier, steht es auch wieder etwas anders:
    https://www.ffmpeg.org/ffmpeg-protoc...#toc-Protocols

    Also wäre es an Stelle von "-timeout" "-rw_timeout 60" zu setzen, was dann explizit heißt: Wirf einen Fehler, wenn 60 Sekunden lang nicht gelesen oder geschrieben werden kann.

    PS: In der Doku steht für timeout mal Millisekunden, mal Sekunden je nach Option
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  3. #28
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Ach oder nicht timeout, das war glaub ich der Cache der mit 1000 war, ich hab ka...

    Mfg

  4. #29

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    @DukeMan999: Für "Caching" ist keine Option gesetzt im Skript, daher sollte dies Standardwert sein den ffmpeg für Caching bzw. als Buffer für den Stream verwendet.
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  5. #30
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Hallöle nochmal,

    ich hab noch eine bitte wegen des scripts, könnte man ggf. eine locale Liste in das script reinladen wo die streams schon drin sind? zB.:

    Code:
    #EXTM3U
    #EXTINF:-1 tvg-name="Das Erste HD" tvg-id="ARD.de" group-title="Vollprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/daserstehd.png",Das Erste HD
    https://daserstehdde-lh.akamaihd.net/i/daserstehd_de@629196/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="ZDF HD" tvg-id="ZDF.de" group-title="Vollprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/zdfhd.png",ZDF HD
    https://zdf1314-lh.akamaihd.net/i/de14_v1@392878/index_3096_av-b.m3u8
    #EXTINF:-1 tvg-name="3sat" tvg-id="3sat.de" group-title="Vollprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/3sat.png",3sat
    https://zdf0910-lh.akamaihd.net/i/dach10_v1@392872/index_1496_av-p.m3u8
    #EXTINF:-1 tvg-name="ARTE HD" tvg-id="ARTE.de" group-title="Vollprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/artehd.png",ARTE HD
    https://artelive-lh.akamaihd.net/i/artelive_de@393591/index_1_av-b.m3u8
    #EXTINF:-1 tvg-name="ServusTV HD" tvg-id="ServusHD.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/servustvhd.png",ServusTV HD
    https://liveservustv-i.akamaihd.net/hls/live/271000/ServusTV_DE/master_rtz2192.m3u8
    #EXTINF:-1 tvg-name="Welt der Wunder" tvg-id="WeltDerWunder.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/weltderwunder.png",Welt der Wunder
    http://live.vidoo.de/live/weltderwunder/master.m3u8
    #EXTINF:-1 tvg-name="ARD-alpha" tvg-id="ARD-alpha.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ardalpha.png",ARD-alpha
    https://brlive-lh.akamaihd.net/i/bralpha_germany@119899/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="one HD" tvg-id="One.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/onehd.png",one HD
    http://onelivestream-lh.akamaihd.net/i/one_livestream@568814/index_7_av-p.m3u8
    #EXTINF:-1 tvg-name="ZDFneo" tvg-id="ZDFneo.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/zdfneo.png",ZDFneo
    https://zdf1314-lh.akamaihd.net/i/de13_v1@392877/index_3096_av-b.m3u8
    #EXTINF:-1 tvg-name="ZDFinfo" tvg-id="ZDFinfo.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/zdfinfo.png",ZDFinfo
    http://zdf1112-lh.akamaihd.net/i/de12_v1@392882/index_3096_av-p.m3u8
    #EXTINF:-1 tvg-name="ANIXE HD" tvg-id="AnixeSerie.de" group-title="Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/anixehd.png",ANIXE HD
    http://video1.anixehd.tv:8080/Apple/wifistream.m3u8
    #EXTINF:-1 tvg-name="blizz TV" tvg-id="Blizz.de" group-title="Filme / Serien" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/blizztv.png",blizz TV
    http://familytvblizz-lh.akamaihd.net/i/familytv_1@458351/master.m3u8
    #EXTINF:-1 tvg-name="Family TV" tvg-id="FamilyTV.de" group-title="Filme / Serien" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/familytv.png",Family TV
    http://familytvblizz-lh.akamaihd.net/i/blizzlive_1@36699/index_500_av-p.m3u8
    #EXTINF:-1 tvg-name="eoTV HD" tvg-id="RiC.de" group-title="Filme / Serien" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/eotvhd.png",eoTV HD
    http://cdn-europe.smartcast.de:1935/eotvhd/eotvhd/playlist.m3u8
    #EXTINF:-1 tvg-name="RiC / eoTV" tvg-id="RiC.de" group-title="Filme / Serien;Kinder / Jugend" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ric.png",RiC / eoTV
    https://58b42f6c8c9bf.streamlock.net/live/rictv/playlist.m3u8
    #EXTINF:-1 tvg-name="KiKA" tvg-id="Kika.de" group-title="Kinder / Jugend" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/kika.png",KiKA
    https://kikade-lh.akamaihd.net/i/livetvkika_de@450035/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="Nickelodeon" tvg-id="Nick.de" group-title="Kinder / Jugend" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/nickelodeon.png",Nickelodeon
    http://unilivemtveu-lh.akamaihd.net/i/nickde_1@448749/index_3500_av-b.m3u8
    #EXTINF:-1 tvg-name="MTV Germany" tvg-id="MTVGermany.de" group-title="Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/mtvgermany.png",MTV Germany
    http://unilivemtveu-lh.akamaihd.net/i/mtvde_1@134922/index_3500_av-p.m3u8
    #EXTINF:-1 tvg-name="DELUXE MUSIC" tvg-id="DeLuxeMusic.de" group-title="Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/deluxemusic.png",DELUXE MUSIC
    http://streaming-02.mivitec.net/live/smil:test.smil/playlist.m3u8
    xxx text mußte gekürzt werden xxx
    #EXTINF:-1 tvg-name="WDR Event 4" tvg-id="WDREvent4.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/wdr.png",WDR Event 4
    http://wdr_event4-lh.akamaihd.net/i/wdrevent4_weltweit@112054/index_1_av-p.m3u8
    #EXTINF:-1 tvg-name="SWR Event 1" tvg-id="SWREvent1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/swr.png",SWR Event 1
    http://swr_event01_uni-lh.akamaihd.net/i/swr_event01@112805/index_3584_av-p.m3u8
    #EXTINF:-1 tvg-name="SWR Event 2" tvg-id="SWREvent2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/swr.png",SWR Event 2
    http://swr_event02_uni-lh.akamaihd.net/i/swr_event02@112806/index_3584_av-p.m3u8
    #EXTINF:-1 tvg-name="SWR Event 3" tvg-id="SWREvent3.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/swr.png",SWR Event 3
    http://swr_event03_uni-lh.akamaihd.net/i/swr_event03@198168/index_3584_av-p.m3u8
    #EXTINF:-1 tvg-name="SWR Event 4" tvg-id="SWREvent4.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/swr.png",SWR Event 4
    http://swr_event04_uni-lh.akamaihd.net/i/swr_event04@198169/index_3584_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Event 1" tvg-id="NDREvent1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Event 1
    http://ndr_events-lh.akamaihd.net/i/ndrevent_1@119220/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Event 2" tvg-id="NDREvent2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Event 2
    http://ndr_events-lh.akamaihd.net/i/ndrevent_2@119221/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Event 3" tvg-id="NDREvent3.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Event 3
    http://ndr_events-lh.akamaihd.net/i/ndrevent_3@119222/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Spezial 1" tvg-id="NDRSpezial1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Spezial 1
    http://ndr_spezial-lh.akamaihd.net/i/spezial_1@119227/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Spezial 2" tvg-id="NDRSpezial2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Spezial 2
    http://ndr_spezial-lh.akamaihd.net/i/spezial_2@119228/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Spezial 3" tvg-id="NDRSpezial3.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Spezial 3
    http://ndr_spezial-lh.akamaihd.net/i/spezial_3@119229/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Spezial 4" tvg-id="NDRSpezial4.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Spezial 4
    http://ndr_spezial-lh.akamaihd.net/i/spezial_4@119230/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Spezial 5" tvg-id="NDRSpezial5.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Spezial 5
    http://ndr_spezial-lh.akamaihd.net/i/spezial_5@384495/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="NDR Spezial 6" tvg-id="NDRSpezial6.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/ndr.png",NDR Spezial 6
    http://ndr_spezial-lh.akamaihd.net/i/spezial_6@364638/index_3776_av-p.m3u8
    #EXTINF:-1 tvg-name="BR Event 1" tvg-id="BREvent1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/br.png",BR Event 1
    http://brevent1hds-lh.akamaihd.net/i/br_event01isma@86390/index_1_av-p.m3u8
    #EXTINF:-1 tvg-name="BR Event 2" tvg-id="BREvent2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/br.png",BR Event 2
    http://brevent1hds-lh.akamaihd.net/i/br_event02isma@111248/index_1_av-p.m3u8
    #EXTINF:-1 tvg-name="BR Event 3" tvg-id="BREvent3.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/br.png",BR Event 3
    http://brevent1hds-lh.akamaihd.net/i/br_event03isma@111249/index_1_av-p.m3u8
    #EXTINF:-1 tvg-name="BR Event 4" tvg-id="BREvent4.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/br.png",BR Event 4
    http://brevent1hds-lh.akamaihd.net/i/br_event04isma@111250/index_1_av-b.m3u8
    #EXTINF:-1 tvg-name="MDR+ 1" tvg-id="MDRPlus1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/mdr.png",MDR+ 1
    http://liveevent1.mdr.de/i/livetvmdrevent1_ww@106904/index_3871_av-p.m3u8
    #EXTINF:-1 tvg-name="MDR+ 2" tvg-id="MDRPlus2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/mdr.png",MDR+ 2
    http://liveevent2.mdr.de/i/livetvmdrevent2_ww@106905/index_3871_av-p.m3u8
    #EXTINF:-1 tvg-name="MDR+ 3" tvg-id="MDRPlus3.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/mdr.png",MDR+ 3
    http://liveevent2.mdr.de/i/livetvmdrevent3_ww@106905/index_3871_av-p.m3u8
    #EXTINF:-1 tvg-name="HR Event 1" tvg-id="HREvent1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/hr.png",HR Event 1
    http://hrevent-lh.akamaihd.net/i/hr_event@309239/master.m3u8
    #EXTINF:-1 tvg-name="HR Event 2" tvg-id="HREvent2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/hr.png",HR Event 2
    http://hrevent2-lh.akamaihd.net/i/hr_event2@309240/master.m3u8
    #EXTINF:-1 tvg-name="rbb Event 1" tvg-id="RBBEvent1.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/rbb.png",rbb Event 1
    http://rbbevent01-lh.akamaihd.net/i/rbbevent01_nongeo@22155/index_2692_av-p.m3u8
    #EXTINF:-1 tvg-name="rbb Event 2" tvg-id="RBBEvent2.de" group-title="Extra" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/rbb.png",rbb Event 2
    https://rbbevent02-lh.akamaihd.net/i/rbbevent02_nongeo@22197/index_2692_av-p.m3u8
    #EXTINF:-1 tvg-name="Parlamentsfernsehen 1" tvg-id="" group-title="Extra;Information / Bildung" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/parlamentsfernsehen.png",Parlamentsfernsehen 1
    https://c13014-l-hls.u.core.cdn.streamfarm.net/1000153copo/hk1.m3u8
    #EXTINF:-1 tvg-name="Parlamentsfernsehen 2" tvg-id="" group-title="Extra;Information / Bildung" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/parlamentsfernsehen.png",Parlamentsfernsehen 2
    https://c13014-l-hls.u.core.cdn.streamfarm.net/1000153copo/hk2.m3u8
    #EXTINF:-1 tvg-name="DJing" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing
    https://www.djing.com/tv/live.m3u8
    #EXTINF:-1 tvg-name="DJing Animation" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Animation
    https://www.djing.com/tv/animation.m3u8
    #EXTINF:-1 tvg-name="DJing Classics" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Classics
    https://www.djing.com/tv/hits.m3u8
    #EXTINF:-1 tvg-name="DJing Electro Rock" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Electro Rock
    https://www.djing.com/tv/session_electro-rock.m3u8
    #EXTINF:-1 tvg-name="DJing French touch" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing French touch
    https://www.djing.com/tv/session_french-touch.m3u8
    #EXTINF:-1 tvg-name="DJing Hedonist" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Hedonist
    https://www.djing.com/tv/session_hedonist.m3u8
    #EXTINF:-1 tvg-name="DJing Hot Hot Hot" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Hot Hot Hot
    https://www.djing.com/tv/h-01-fta.m3u8
    #EXTINF:-1 tvg-name="DJing Ibiza" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Ibiza
    https://www.djing.com/tv/dancefloor.m3u8
    #EXTINF:-1 tvg-name="DJing Karaoke" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Karaoke
    https://www.djing.com/tv/karaoke.m3u8
    #EXTINF:-1 tvg-name="DJing Summer Vibes" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Summer Vibes
    https://www.djing.com/tv/session_summer-vibes.m3u8
    #EXTINF:-1 tvg-name="DJing Underground" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Underground
    https://www.djing.com/tv/underground.m3u8
    #EXTINF:-1 tvg-name="DJing Wild EDM" tvg-id="" group-title="Extra;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/djing.png",DJing Wild EDM
    http://www.djing.com/tv/session_wild-edm.m3u8
    #EXTINF:-1 tvg-name="ServusTV HD (AT)" tvg-id="ServusTV.at" group-title="International;Spartenprogramm" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/servustvhd.png",ServusTV HD (AT)
    http://hdiosstv-f.akamaihd.net/i/servustvhd_1@51229/index_2592_av-p.m3u8
    #EXTINF:-1 tvg-name="gotv" tvg-id="Gotv.at" group-title="International;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/gotv.png",gotv
    http://nstream17.gotv.at:1938/live/gotvlive_576p/playlist.m3u8
    #EXTINF:-1 tvg-name="Okto" tvg-id="OKTO.at" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/okto.png",Okto
    https://d2jk87psbjrjdz.cloudfront.net/livehttporigin/okto/playlist.m3u8
    #EXTINF:-1 tvg-name="ORF eins HD" tvg-id="ORF1.at" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/orf1hd.png",ORF eins HD
    https://orf1.cdn.ors.at/out/u/orf1/qxb/manifest_6.m3u8
    #EXTINF:-1 tvg-name="ORF 2 HD" tvg-id="ORF2.at" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/orf2hd.png",ORF 2 HD
    https://orf2.cdn.ors.at/out/u/orf2/qxb/manifest_6.m3u8
    #EXTINF:-1 tvg-name="ORF III HD" tvg-id="ORF3.at" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/orf3hd.png",ORF III HD
    https://orf3.cdn.ors.at/out/u/orf3/qxb/manifest_6.m3u8
    #EXTINF:-1 tvg-name="ORF SPORT +" tvg-id="ORFSport.at" group-title="International;Sport" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/orfsportplushd.png",ORF SPORT +
    https://orfs.cdn.ors.at/out/u/orfs/qxb/manifest_6.m3u8
    #EXTINF:-1 tvg-name="dorf tv" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/dorftv.png",dorf tv
    https://stream.openplayout.org/hls/dorf_high/index.m3u8
    #EXTINF:-1 tvg-name="RE eins TV" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/reeins.png",RE eins TV
    http://www.reeins.tv:1935/live/re1/playlist.m3u8
    #EXTINF:-1 tvg-name="Tirol TV" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/tiroltv.png",Tirol TV
    http://lb.hd-livestream.de:1935/live/TirolTV/playlist.m3u8
    #EXTINF:-1 tvg-name="oe24 TV" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/oe24tv.png",oe24 TV
    http://apasfoe24l.sf.apa.at/ipad/oe24-live1/oe24.sdp/playlist.m3u8
    #EXTINF:-1 tvg-name="M4TV" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/m4tv.png",M4TV
    http://streaming.austria24.tv/live/stream_720p/playlist.m3u8
    #EXTINF:-1 tvg-name="W24 TV" tvg-id="W24.at" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/w24.png",W24 TV
    http://ms02.w24.at/hls-live/livepkgr/_definst_/liveevent/livestream3.m3u8
    #EXTINF:-1 tvg-name="Kronehit TV" tvg-id="" group-title="International;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/kronehittv.png",Kronehit TV
    https://bitcdn-kronehit.bitmovin.com/v2/hls/chunklist_b3128000.m3u8
    #EXTINF:-1 tvg-name="Sporttime TV 1" tvg-id="" group-title="International;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/sporttimetv.png",Sporttime TV 1
    http://sporttimelive1.content-cdn.net/livechannel1/smil:switch1.smil/playlist.m3u8?wowzatokenhash=sUTjnxXLdal6Y8bBzs9an_zhqn7VrgWUS5uB8sckoCw=
    #EXTINF:-1 tvg-name="Sporttime TV 2" tvg-id="" group-title="International;Sport" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/sporttimetv.png",Sporttime TV 2
    http://sporttimelive1.content-cdn.net/livechannel2/smil:switch2.smil/playlist.m3u8?wowzatokenhash=qgtY96D77QocQoiJn6MCsyHbBMGla2uQoQ03XvQYkuE=
    #EXTINF:-1 tvg-name="Sporttime TV 4" tvg-id="" group-title="International;Information / Bildung" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/sporttimetv.png",Sporttime TV 4
    http://sporttimelive1.content-cdn.net/livechannel4/smil:switch4.smil/playlist.m3u8?wowzatokenhash=BhYr7Qu4cZ8LgxWiF7cuQ_hA7sxqdon5Kw0sIHJ7TpM=
    #EXTINF:-1 tvg-name="Sporttime TV 5" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/sporttimetv.png",Sporttime TV 5
    http://live.earthtv.com:1935/edge27/TWLDE/playlist.m3u8?58a36274bbf047f6c3b5cdb1
    #EXTINF:-1 tvg-name="TeleZüri HD" tvg-id="TeleZuri.ch" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/telezueri.png",TeleZüri HD
    https://klive-a.akamaihd.net/dc-1/live/hls/p/1719221/e/1_hoislpiz/sd/10000/t/AFb4DZ0W2ts1a8fV5xo1VQ/index-s32.m3u8
    #EXTINF:-1 tvg-name="TeleBärn HD" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/telebaern.png",TeleBärn HD
    http://klive-a.akamaihd.net/dc-1/live/hls/p/1719221/e/1_0mc3z57p/sd/10000/t/XTGwenpKUhx_fbVnsiu9MQ/index-s32.m3u8
    #EXTINF:-1 tvg-name="Tele M1 HD" tvg-id="TeleM1.ch" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/telem1.png",Tele M1 HD
    http://klive-a.akamaihd.net/dc-1/live/hls/p/1719221/e/1_ljzy3evp/sd/10000/t/nwOKUovT2mwnA8x_KnC4zg/index-s32.m3u8
    #EXTINF:-1 tvg-name="TVO (CH)" tvg-id="TVO.ch" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/tvo_ch.png",TVO (CH)
    http://livevideo.infomaniak.com/streaming/livecast/tvo/playlist.m3u8
    #EXTINF:-1 tvg-name="TeleBielingue" tvg-id="TeleBielingue.ch" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/telebielingue.png",TeleBielingue
    http://livevideo.infomaniak.com/streaming/livecast/telebielinguech/playlist.m3u8
    #EXTINF:-1 tvg-name="TVM3" tvg-id="TVM3.ch" group-title="International;Musik" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/tvm3.png",TVM3
    https://tvm3.vedge.infomaniak.com/livecast/tvm3/playlist.m3u8
    #EXTINF:-1 tvg-name="Telebasel" tvg-id="" group-title="International" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/telebasel.png",Telebasel
    http://xapp510394368c1000199.f.l.z.lb.core-cdn.net/10096xtelebase/ios_500/master.m3u8
    #EXTINF:-1 tvg-name="ABC News" tvg-id="" group-title="International;Nachrichten" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/abcnews.png",ABC News
    https://abclive1-lh.akamaihd.net/i/abc_live04@423398/index_4000_av-b.m3u8
    #EXTINF:-1 tvg-name="Adult Swim" tvg-id="" group-title="International;Comedy" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/adultswim.png",Adult Swim
    http://adultswimhls-i.akamaihd.net/hls/live/238460/adultswim/main/1/master.m3u8
    #EXTINF:-1 tvg-name="JUCE TV" tvg-id="" group-title="International;Religion;Kinder / Jugend" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/jucetv.png",JUCE TV
    http://acaooyalahd2-lh.akamaihd.net/i/TBN03_delivery@186241/index_1728_av-p.m3u8
    #EXTINF:-1 tvg-name="NASA TV" tvg-id="NASA.us" group-title="International;Information / Bildung" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/nasatv.png",NASA TV
    https://nasa-i.akamaihd.net/hls/live/253565/NASA-NTV1-Public/master.m3u8
    #EXTINF:-1 tvg-name="CBSN" tvg-id="" group-title="International;Nachrichten" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/cbsn.png",CBSN
    https://cbsnhls-i.akamaihd.net/hls/live/264710/CBSN_mdialog/prodstream/master_2200.m3u8
    #EXTINF:-1 tvg-name="CBN News" tvg-id="" group-title="International;Nachrichten" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/cbnnews.png",CBN News
    http://bcliveuniv-lh.akamaihd.net/i/news_1@194050/index_900_av-b.m3u8
    #EXTINF:-1 tvg-name="Bloomberg TV" tvg-id="Bloomberg.nws" group-title="International;Wirtschaft" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/bloombergtv.png",Bloomberg TV
    xxx text gekürzt xxx
    #EXTINF:-1 tvg-name="DELUXE CHEFSESSEL by WAGNER" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeradio.png",DELUXE CHEFSESSEL by WAGNER
    https://deluxe-radio.mivitec.net:8443/0011
    #EXTINF:-1 tvg-name="DELUXE EASY" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeeasy.png",DELUXE EASY
    https://deluxe-radio.mivitec.net:8443/0009
    #EXTINF:-1 tvg-name="DELUXE LOUNGE RADIO" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeloungeradio.png",DELUXE LOUNGE RADIO
    https://deluxe-radio.mivitec.net:8443/0010
    #EXTINF:-1 tvg-name="DELUXE MUSIC RADIO" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxemusicradio.png",DELUXE MUSIC RADIO
    https://deluxe-radio.mivitec.net:8443/0005
    #EXTINF:-1 tvg-name="DELUXE NEW ARRIVALS" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeradio.png",DELUXE NEW ARRIVALS
    https://deluxe-radio.mivitec.net:8443/0006
    #EXTINF:-1 tvg-name="DELUXE TOP 25" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeradio.png",DELUXE TOP 25
    https://deluxe-radio.mivitec.net:8443/0008
    #EXTINF:-1 tvg-name="Deutschlandfunk" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deutschlandfunk.png",Deutschlandfunk
    http://st01.dlf.de/dlf/01/128/mp3/stream.mp3
    #EXTINF:-1 tvg-name="Deutschlandfunk Kultur" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deutschlandfunkkultur.png",Deutschlandfunk Kultur
    http://st02.dlf.de/dlf/02/128/mp3/stream.mp3
    #EXTINF:-1 tvg-name="Deutschlandfunk Nova" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deutschlandfunknova.png",Deutschlandfunk Nova
    http://st03.dlf.de/dlf/03/128/mp3/stream.mp3
    #EXTINF:-1 tvg-name="Deutschlandradio Dokumente und Debatten" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deutschlandradiodud.png",Deutschlandradio Dokumente und Debatten
    http://st04.dlf.de/dlf/04/128/mp3/stream.mp3
    #EXTINF:-1 tvg-name="DIE NEUE 107.7" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/dieneue1077.png",DIE NEUE 107.7
    http://dieneue1077.cast.addradio.de/dieneue1077/simulcast/high/stream.mp3
    #EXTINF:-1 tvg-name="DISCO DELUXE" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeradio.png",DISCO DELUXE
    https://deluxe-radio.mivitec.net:8443/0003
    #EXTINF:-1 tvg-name="domradio.de" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/domradiode.png",domradio.de
    http://domradio-mp3-l.akacast.akamaistream.net/7/809/237368/v1/gnl.akacast.akamaistream.net/domradio-mp3-l
    #EXTINF:-1 tvg-name="DONAU 3 FM" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/donau3fm.png",DONAU 3 FM
    http://mp3.donau3fm.c.nmdn.net/donau3fm/live.mp3
    #EXTINF:-1 tvg-name="egoFM" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/egofm.png",egoFM
    http://mp3ad.egofm.c.nmdn.net/ps-egofm_192/livestream.mp3
    #EXTINF:-1 tvg-name="ERF Plus" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/erfplus.png",ERF Plus
    http://c14000-l.i.core.cdn.streamfarm.net/14000cina/live/3212erf_96/live_de_96.mp3
    #EXTINF:-1 tvg-name="ERF Pop" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/erfpop.png",ERF Pop
    http://c14000-l.i.core.cdn.streamfarm.net/14000cina/live/2908erfpop/live_de_96.mp3
    #EXTINF:-1 tvg-name="FluxFM" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/fluxfm.png",FluxFM
    http://streams.fluxfm.de/live/mp3-320/audio/
    #EXTINF:-1 tvg-name="Fritz" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/fritz.png",Fritz
    http://rbb-fritz-live.cast.addradio.de/rbb/fritz/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="harmony.fm" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/harmonyfm.png",harmony.fm
    http://mp3ad.harmony.c.nmdn.net/fs_harmonyfm/hqlivestream.mp3
    #EXTINF:-1 tvg-name="HIT RADIO FFH" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/hitradioffh.png",HIT RADIO FFH
    http://mp3.ffh.de/radioffh/hqlivestream.mp3
    #EXTINF:-1 tvg-name="hr-info" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/hrinfo.png",hr-info
    http://hr-hrinfo-live.cast.addradio.de/hr/hrinfo/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="hr1" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/hr1.png",hr1
    http://hr-hr1-live.cast.addradio.de/hr/hr1/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="hr2-kultur" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/hr2kultur.png",hr2-kultur
    http://hr-hr2-live.cast.addradio.de/hr/hr2/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="hr3" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/hr3.png",hr3
    http://hr-hr3-live.cast.addradio.de/hr/hr3/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="hr4" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/hr4.png",hr4
    http://hr-hr4-live.cast.addradio.de/hr/hr4/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="JAM FM" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/jamfm.png",JAM FM
    http://stream.jam.fm/jamfm-live/mp3-128/konsole/
    #EXTINF:-1 tvg-name="JAM FM Black Label" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/jamfm.png",JAM FM Black Label
    http://stream.jam.fm/jamfm-bl/mp3-128/konsole/
    #EXTINF:-1 tvg-name="JAM FM New Music Radio" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/jamfm.png",JAM FM New Music Radio
    http://stream.jam.fm/jamfm-nmr/mp3-128/konsole/
    #EXTINF:-1 tvg-name="JUKEBOX RADIO" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/deluxeradio.png",JUKEBOX RADIO
    https://deluxe-radio.mivitec.net:8443/0004
    #EXTINF:-1 tvg-name="KiRaKa" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/kiraka.png",KiRaKa
    http://wdr-kiraka-live.icecast.wdr.de/wdr/kiraka/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="KULTRADIO" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/kultradio.png",KULTRADIO
    http://ice.kultradio.fm/kult128.mp3
    #EXTINF:-1 tvg-name="LandesWelle Thüringen" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/landeswellethueringen.png",LandesWelle Thüringen
    http://stream.landeswelle.de/lwt/mp3-192
    #EXTINF:-1 tvg-name="MDR AKTUELL" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdraktuell.png",MDR AKTUELL
    http://mdr-284340-0.cast.mdr.de/mdr/284340/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="MDR JUMP" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdrjump.png",MDR JUMP
    http://mdr-284320-0.cast.mdr.de/mdr/284320/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="MDR KLASSIK" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdrklassik.png",MDR KLASSIK
    http://mdr-284350-0.cast.mdr.de/mdr/284350/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="MDR KULTUR" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdrkultur.png",MDR KULTUR
    http://mdr-284310-0.cast.mdr.de/mdr/284310/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="MDR SACHSEN" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdrsachsen.png",MDR SACHSEN
    http://mdr-284280-0.cast.mdr.de/mdr/284280/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="MDR SPUTNIK" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdrsputnik.png",MDR SPUTNIK
    http://mdr-284330-0.cast.mdr.de/mdr/284330/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="MDR THÜRINGEN" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/mdrthueringen.png",MDR THÜRINGEN
    http://mdr-284300-0.cast.mdr.de/mdr/284300/0/mp3/high/stream.mp3
    #EXTINF:-1 tvg-name="multicult.fm" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/multicultfm.png",multicult.fm
    http://stream.multicult.fm:8000/hifi
    #EXTINF:-1 tvg-name="N-JOY" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/njoy.png",N-JOY
    http://ndr-njoy-live.cast.addradio.de/ndr/njoy/live/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="NDR 1 Niedersachsen" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/ndr1niedersachsen.png",NDR 1 Niedersachsen
    http://ndr-ndr1niedersachsen-hannover.cast.addradio.de/ndr/ndr1niedersachsen/hannover/mp3/128/stream.mp3
    #EXTINF:-1 tvg-name="Radio 538 Hitzone" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radio538.png",Radio 538 Hitzone
    http://vip-icecast.538.lw.triple-it.nl/WEB11_MP3
    #EXTINF:-1 tvg-name="Radio 538 Ibiza" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radio538.png",Radio 538 Ibiza
    http://vip-icecast.538.lw.triple-it.nl/WEB19_MP3
    #EXTINF:-1 tvg-name="Radio 538 Non-Stop" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radio538.png",Radio 538 Non-Stop
    http://vip-icecast.538.lw.triple-it.nl/WEB09_MP3
    #EXTINF:-1 tvg-name="Radio 538 Party" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radio538.png",Radio 538 Party
    http://vip-icecast.538.lw.triple-it.nl/WEB16_MP3
    #EXTINF:-1 tvg-name="Radio 538 Top 40 Radio" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radio538.png",Radio 538 Top 40 Radio
    http://vip-icecast.538.lw.triple-it.nl/WEB02_MP3
    #EXTINF:-1 tvg-name="Radio 538 Verrückte Stunde" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radio538.png",Radio 538 Verrückte Stunde
    http://vip-icecast.538.lw.triple-it.nl/WEB21_MP3
    #EXTINF:-1 tvg-name="Radio Veronica" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radioveronica.png",Radio Veronica
    http://playerservices.streamtheworld.com/api/livestream-redirect/VERONICA.mp3
    #EXTINF:-1 tvg-name="Sky Radio 101 FM" group-title="Niederlande" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/skyradio101fm.png",Sky Radio 101 FM
    http://playerservices.streamtheworld.com/api/livestream-redirect/SKYRADIO.mp3
    #EXTINF:-1 tvg-name="Planeta FM" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/planetafm.png",Planeta FM
    http://pla01.cdn.eurozet.pl:8700/pla-net.mp3
    #EXTINF:-1 tvg-name="Planeta FM Dope Hits" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/planetafm.png",Planeta FM Dope Hits
    http://pla02.cdn.eurozet.pl:8208/PLAHOU.mp3
    #EXTINF:-1 tvg-name="Planeta FM Electronic Wave" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/planetafm.png",Planeta FM Electronic Wave
    http://pla02.cdn.eurozet.pl:8228/PLAEDM.mp3
    #EXTINF:-1 tvg-name="Planeta FM Good Vibes" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/planetafm.png",Planeta FM Good Vibes
    http://pla01.cdn.eurozet.pl:8204/PLACHI.mp3
    #EXTINF:-1 tvg-name="Planeta FM Indie Day Mood" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/planetafm.png",Planeta FM Indie Day Mood
    http://pla02.cdn.eurozet.pl:8230/PLAIDM.mp3
    #EXTINF:-1 tvg-name="Radio ZET" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET
    http://n-4-14.dcs.redcdn.pl/sc/o2/Eurozet/live/audio.livx?audio=5
    #EXTINF:-1 tvg-name="Radio ZET 2000" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET 2000
    http://zet.cdn.eurozet.pl/ZET200.mp3
    #EXTINF:-1 tvg-name="Radio ZET 80" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET 80
    http://zet.cdn.eurozet.pl/ZET080.mp3
    #EXTINF:-1 tvg-name="Radio ZET 90" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET 90
    http://zet.cdn.eurozet.pl/ZET090.mp3
    #EXTINF:-1 tvg-name="Radio ZET Dance" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET Dance
    http://zet.cdn.eurozet.pl/ZETDAN.mp3
    #EXTINF:-1 tvg-name="Radio ZET Hits" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET Hits
    http://zet.cdn.eurozet.pl/ZETHIT.mp3
    #EXTINF:-1 tvg-name="Radio ZET Hot" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET Hot
    http://zet.cdn.eurozet.pl/ZETHOT.mp3
    #EXTINF:-1 tvg-name="Radio ZET Party" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET Party
    http://zet.cdn.eurozet.pl/ZETPAR.mp3
    #EXTINF:-1 tvg-name="Radio ZET PL" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET PL
    http://zet.cdn.eurozet.pl/ZETPL1.mp3
    #EXTINF:-1 tvg-name="Radio ZET Rock" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/radiozet.png",Radio ZET Rock
    http://zet.cdn.eurozet.pl/ZETROK.mp3
    #EXTINF:-1 tvg-name="RMF FM" group-title="Polen" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/rmffm.png",RMF FM
    http://195.150.20.243/RMFFM48
    sprich das er die in dem falle nicht online erst holen muß? Würde der denn auch nur Audio aufnehmen können? Da ich da ein paar radio sender auch mit reingepackt habe...

    Das Zweite wäre wenn der ffmpeg nicht gehen "würde" das man den auch local daneben im Ordner runtergeladen hat, das er dann das in dem Ordner nutzen könnte?

    MfG

  6. #31

    Thumbs up Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    @DukeMan999:

    Also, zum Punkt, lokale FFmpeg Kopie, geht. Mp3 Streams, geht auch, wenn die URL funktioniert. Da gibt es keinen Test oder eine Warnung ob ein Video/Radiostream verfügbar ist oder nicht. Das hängt von der Playliste ab.

    Nutzung:
    python3 rec.py -localLOCALE_PLAYLIST.m3u8

    Hier wird die lokale Playliste "LOCALE_PLAYLIST.m3u8" geladen und auch später bei Aufnahme geladen. Dabei werden Radiosender mit "(Radio)" gekennzeichnet, so fern es sich um einen Radiosender handelt. Die Erkennung hängt von der m3u8 Parameter - radio="true" - ab. Diese werden als ".mp3" gespeichert.

    Ansonsten arbeitet das Skript wie gehabt.

    Um eine andere FFmpeg Version zu nehmen, außer die auf dem System installierte, kann man das wie folgt in einen Parameter eingeben:
    Code (Python):
    1. FFMPEG_DIRECTORY = 'ffmpeg'  # OR PATH: /home/username/path_to_ffmpeg/./ffmpeg OR leave 'ffmpeg' for general ffmpeg usage from system
    Es kann sein das, wenn der Pfad angegeben wird zu FFMpeg - das "chmod +x" für die Datei gesetzt werden muss. Und auch wichtig das: "./ffmpeg" - damit diese Version ausgeführt wird.

    Fragen?

    PS: Ich habe ebenfalls die "timeout" rausgenommen, das gab öfter Probleme, also daher der Standardwert dafür.

    Code:

    Spoiler: 

    Code:
    1. #!/usr/bin/env python3
    2. import sys
    3. import time
    4. import glob
    5. import subprocess
    6. import os.path
    7. import os
    8.  
    9. import pycurl
    10.  
    11. USE_AT = True
    12. PLAYLIST_URL = ".m3u8"
    13. USER_AGENT = "Your custom useragent"
    14. FFMPEG_DIRECTORY = 'ffmpeg'  # OR PATH: /home/username/path_to_ffmpeg/./ffmpeg OR leave 'ffmpeg' for general ffmpeg usage from system
    15. #FFMPEG_DIRECTORY = '/home/username/ffmpeg_4.1.4-1+b2_amd64/./ffmpeg' # example
    16.  
    17. APP_FOLDER = os.getcwd()
    18.  
    19. PLAYLIST_FILE = "streamTempSave.m3u8" # This is just a temporary storage for the downloaded playlist, but this file wont be removed by itself
    20. PLAYLIST_DATA = ""
    21. PLAYLIST_CHANNELS = {}
    22. RECORDING_NAME = ""
    23. RECORDING_CHANNEL_NAME = ""
    24. RECORDING_CHANNEL_URL = ""
    25. RECORDING_TIME = 0
    26. RECORDING_DURATION = 0
    27.  
    28. def downloadPlaylist(downloadURL):
    29.     playlistFile = open(PLAYLIST_FILE, "wb")
    30.  
    31.     print('Starting download of URI: \'%s\'\n' % downloadURL)
    32.     c = pycurl.Curl()
    33.     c.setopt(pycurl.URL, downloadURL)
    34.     c.setopt(pycurl.USERAGENT, USER_AGENT)
    35.     c.setopt(pycurl.VERBOSE, False)
    36.     c.setopt(pycurl.ENCODING, 'utf-8')
    37.     c.setopt(pycurl.WRITEDATA, playlistFile)
    38.     c.setopt(pycurl.NOPROGRESS, True)
    39.     c.setopt(pycurl.TIMEOUT, 30)
    40.  
    41.     try:
    42.         c.perform()
    43.         print("\nSuccessfully downloaded playlist.\n")
    44.         playlistFile.close()
    45.         c.close()
    46.         return True
    47.     except Exception as error:
    48.         playlistFile.close()
    49.         c.close()
    50.         print("Encountered an error:")
    51.         raise error
    52.     return False
    53.  
    54.  
    55.  
    56. def getStreamSelection():
    57.     global PLAYLIST_CHANNELS, RECORDING_CHANNEL_NAME, RECORDING_CHANNEL_URL
    58.  
    59.     playlistFile = open(PLAYLIST_FILE, "r")
    60.     data = playlistFile.readlines()
    61.  
    62.     currentChannel = None
    63.     for line in data:
    64.         if line.startswith('#EXTINF:'):
    65.             currentChannel = line.split(',',2)[1].rstrip().rstrip('"').replace('tvg-name="', '')
    66.             if line.find('radio="true"') != -1:
    67.                 currentChannel += ' (Radio)'
    68.         elif (currentChannel != None and line.startswith('http')):
    69.             PLAYLIST_CHANNELS[currentChannel] = line
    70.             currentChannel = None
    71.  
    72.     sortedChannels = sorted(PLAYLIST_CHANNELS.keys())
    73.  
    74.     print("\nChannel selection:")
    75.     for index, channel in enumerate(sortedChannels):
    76.         print("%2d - %s" % (index, channel))
    77.  
    78.     print("x - Exit")
    79.  
    80.     print("\n")
    81.  
    82.     while True:
    83.         channelNum = input("\nInput channel number for grabbing: ")
    84.         if channelNum.lower() == "x":
    85.             exit(0)
    86.         else:
    87.             try:
    88.                 RECORDING_CHANNEL_URL = PLAYLIST_CHANNELS[sortedChannels[int(channelNum)]].rstrip()
    89.                 RECORDING_CHANNEL_NAME = sortedChannels[int(channelNum)]
    90.  
    91.                 print("Selected recording channel: %s" % (sortedChannels[int(channelNum)]))
    92.                 isValidSelection = input('Is the channel correct Y/N? ')
    93.                 if isValidSelection.lower() == "y":
    94.                     return True
    95.                 else:
    96.                     continue
    97.  
    98.             except Exception:
    99.                 print('Wrong channel selection. Enter a channel number or "x" to exit.')
    100.                 continue
    101.             break
    102.  
    103.  
    104. if __name__ == "__main__":
    105.     hasPlaylist = False
    106.     ISWEBDL = False
    107.     if len(sys.argv) == 1:
    108.         if downloadPlaylist(PLAYLIST_URL):
    109.             hasPlaylist = True
    110.             ISWEBDL = True
    111.             print("Playlist succesfully downloaded.\n")
    112.         else:
    113.             print('Cannot download playlist "%s"' %(PLAYLIST_URL))
    114.             exit(1)
    115.     else:
    116.         for opt in sys.argv:
    117.             if opt.startswith('-local'):
    118.                 playlistName = opt.replace('-local', '', 1)
    119.                 if os.path.exists(playlistName):
    120.                     print('Using local playlist: %s' % (playlistName))
    121.                     PLAYLIST_FILE = playlistName
    122.                     hasPlaylist = True
    123.                     ISWEBDL = False
    124.                 else:
    125.                     print('Playlist not found using name "%s": ' %(playlistName))
    126.                     exit(1)
    127.  
    128.  
    129.     if hasPlaylist and getStreamSelection():
    130.         print('\nIt\'s time to enter the date and time for the recording:')
    131.         while True:
    132.             while True:
    133.                 recordDate = input('\nEnter record date for recording, in format day.month.year, for example: 7.8.2019 or "x" to cancel, enter nothing for todays date.\n')
    134.                 if recordDate.lower() == 'x':
    135.                     print("Cancelled")
    136.                     exit(1)
    137.  
    138.                 elif len(recordDate) == 0:
    139.                     timeNow = time.gmtime()
    140.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    141.                     recordDay = timeNow.tm_mday
    142.                     recordMonth = timeNow.tm_mon
    143.                     recordYear = timeNow.tm_year
    144.  
    145.                     print("Record date: %02d.%02d.%d " %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year))
    146.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    147.                         continue
    148.                     break
    149.  
    150.                 elif recordDate.count('.') == 2:
    151.                     recordDay, recordMonth, recordYear = map(int, recordDate.split('.', 3))
    152.                     timeNow = time.gmtime()
    153.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    154.  
    155.                     try:
    156.                         timestampRecord = time.strptime("%d.%d.%d 00:00:00" %(recordDay, recordMonth, recordYear), "%d.%m.%Y %H:%M:%S")
    157.                     except ValueError:
    158.                         print('Date input does not match, use day.month.year as: 7.8.2019')
    159.                         continue
    160.  
    161.                     if time.mktime(timestampNow) > time.mktime(timestampRecord):
    162.                         print("Date is in the past. Repeat input.")
    163.                     else:
    164.                         print("Record date: %02d.%02d.%d " %(recordDay, recordMonth, recordYear))
    165.  
    166.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    167.                         continue
    168.                     break
    169.                 else:
    170.                     print("Invalid date input.")
    171.                     continue
    172.  
    173.             while True:
    174.                 recordTime = input('\nEnter time to start recording, in format hour:minute, for example: 14:00 for 14 o\'clock, "x" to cancel\n')
    175.                 if recordTime.lower() == 'x':
    176.                     print("Cancelled")
    177.                     exit(1)
    178.                 elif recordTime.find(':') != -1:
    179.                     recordHour, recordMinute = map(int, recordTime.split(':', 2))
    180.                     print("Record time: %02d:%02d " %(recordHour, recordMinute))
    181.  
    182.                     timeNow = time.time()
    183.                     timestampRecord = time.strptime("%d.%d.%d %d:%d:00" %(recordDay, recordMonth, recordYear, recordHour, recordMinute), "%d.%m.%Y %H:%M:%S")
    184.  
    185.  
    186.                     if (timeNow > time.mktime(timestampRecord)):
    187.                         print("Time is in the past. Repeat input.")
    188.                         continue
    189.  
    190.                     if input("Is the record time correct, Y/N ? ").lower() != 'y':
    191.                         continue
    192.  
    193.                     RECORDING_TIME = time.mktime(timestampRecord)
    194.                     break
    195.                 else:
    196.                     print("Invald time input.")
    197.                     continue
    198.  
    199.             while True:
    200.                 recordDuration = input('\nEnter duration in minutes to record. For example 90 to capture 1 1/2 hours, "x" to cancel\n')
    201.                 if recordDuration.lower() == 'x':
    202.                     print("Cancelled")
    203.                     exit(1)
    204.                 elif int(recordDuration) < 0:
    205.                     print("Negative recording duration, enter 30 for 30 minutes.")
    206.                     continue
    207.  
    208.                 print("Record duration: %d minutes " %(int(recordDuration)))
    209.  
    210.                 if input("Is the record time correct, Y/N ? ").lower() != 'y':
    211.                     continue
    212.  
    213.                 RECORDING_DURATION = int(recordDuration)
    214.                 break
    215.  
    216.  
    217.             while True:
    218.                 RECORDING_NAME = input('\nEnter name for the recording file. Enter "x" to cancel\n')
    219.                 if recordDuration.lower() == 'x':
    220.                     print("Cancelled")
    221.                     exit(1)
    222.  
    223.                 print("Record name: %s" % (RECORDING_NAME))
    224.                 if input("Is the record name correct, Y/N ? ").lower() != 'y':
    225.                     continue
    226.  
    227.                 break
    228.  
    229.  
    230.  
    231.             print("\nWhat will be done?\nRecording channel \"%s\"." %(RECORDING_CHANNEL_NAME))
    232.             print("On %s at %s o'clock for %d minutes.\nRecording to file: \"%s\"" %(time.strftime("%d.%m.%Y", time.localtime(RECORDING_TIME)), time.strftime("%H:%M:%S", time.localtime(RECORDING_TIME)), RECORDING_DURATION, RECORDING_NAME))
    233.  
    234.             confirm = input("\nAre all information correct, Y/N? ")
    235.             if confirm.lower() != 'y':
    236.                 continue
    237.  
    238.             scheduleFileName = "%d.rec" %(time.time())
    239.             with open(scheduleFileName, "w") as scheduleFile:
    240.                 scheduleFile.write("%d;%d;%s;%s\n" % (RECORDING_TIME, RECORDING_DURATION, RECORDING_CHANNEL_NAME, RECORDING_NAME))
    241.  
    242.                 if USE_AT:
    243.                     if not ISWEBDL:
    244.                         scheduleCommand = 'echo "python3 %s/rec.py -ldl%s -pf%s" | at -M %s' % (APP_FOLDER, scheduleFileName, PLAYLIST_FILE, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    245.                     else:
    246.                         scheduleCommand = 'echo "python3 %s/rec.py -dl%s" | at -M %s' % (APP_FOLDER, scheduleFileName, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    247.                     subprocess.Popen(scheduleCommand, shell=True)
    248.                     print("Scheduled task.\nBye bye.")
    249.                     exit(1)
    250.  
    251.                 break
    252.  
    253.             print('Error writing schedule file for recording job.')
    254.  
    255.     else:
    256.         hasPlaylist = False
    257.         for opt in sys.argv:
    258.             if opt.startswith('-dl'):
    259.                 if downloadPlaylist(PLAYLIST_URL):
    260.                     hasPlaylist = True
    261.                     print("Playlist succesfully downloaded.\n")
    262.                 else:
    263.                     print("Error downloading playlist from \"%s\".\nExiting." %(PLAYLIST_URL))
    264.                     exit(1)
    265.             elif opt.startswith('-pf'):
    266.                 playlistName = opt.replace('-pf', '', 1)
    267.                 if os.path.exists(playlistName):
    268.                     print('Using local playlist: %s' %(playlistName))
    269.                     PLAYLIST_FILE = playlistName
    270.                 else:
    271.                     print('Playlist not found using name "%s": ' % (playlistName))
    272.                     exit(1)
    273.  
    274.  
    275.         for opt in sys.argv:
    276.             if opt.startswith('-dl'):
    277.                 with open(PLAYLIST_FILE, "r") as playlistFile:
    278.                     data = playlistFile.readlines()
    279.  
    280.                     currentChannel = None
    281.                     for line in data:
    282.                         currentChannel = line.split(',',2)[1].rstrip().rstrip('"').replace('tvg-name="', '')
    283.                         if line.find('radio="true"') != -1:
    284.                             currentChannel += ' (Radio)'
    285.                         elif (currentChannel != None and line.startswith('http')):
    286.                             PLAYLIST_CHANNELS[currentChannel] = line.rstrip()
    287.                             currentChannel = None
    288.  
    289.                     scheduleFileName = opt.replace('-dl', '', 1)
    290.             elif opt.startswith('-ldl'):
    291.                 hasPlaylist = False
    292.                 for subopt in sys.argv:
    293.                     if subopt.startswith('-pf'):
    294.                         PLAYLIST_FILE = subopt.replace('-pf', '', 1)
    295.                         hasPlaylist = True
    296.                         break
    297.  
    298.  
    299.                 with open(PLAYLIST_FILE, "r") as playlistFile:
    300.                     data = playlistFile.readlines()
    301.  
    302.                     currentChannel = None
    303.                     for line in data:
    304.                         if line.startswith('#EXTINF:'):
    305.                             currentChannel = line.split(',',2)[1].rstrip().rstrip('"').replace('tvg-name="', '')
    306.                             if line.find('radio="true"') != -1:
    307.                                 currentChannel += ' (Radio)'
    308.                         elif (currentChannel != None and line.startswith('http')):
    309.                             PLAYLIST_CHANNELS[currentChannel] = line.rstrip()
    310.                             currentChannel = None
    311.  
    312.                 scheduleFileName = opt.replace('-ldl', '', 1)
    313.  
    314.         scheduleFile = None
    315.         if os.path.exists(scheduleFileName):
    316.             scheduleData = None
    317.  
    318.             with open(scheduleFileName, "r") as scheduleFile:
    319.                 scheduleData = scheduleFile.read().rstrip().split(';', 4)
    320.  
    321.             if scheduleData != None:
    322.                 try:
    323.                     channelURL = PLAYLIST_CHANNELS[scheduleData[2]]
    324.                     if scheduleData[2].find(' (Radio)') != -1:
    325.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 '%s.mp3'" %(USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    326.                     else:
    327.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 -vc:copy -o '%s.mkv'" % (USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    328.                     subprocess.Popen(commandString, shell=True)
    329.                 except ValueError as error:
    330.                     print('No channel information found.')
    331.                     raise error
    332.  
    Angehängte Dateien Angehängte Dateien
    Geändert von theSplit (15.09.19 um 18:35 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  7. #32
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Hi,

    jut jut, das werd ich auch mal ausprobieren... werd mal das rein editieren wenns probs gibt. Ich geb den Ordner und unterordner direkt immer alle rechte damit das script bzw python3 auch schreiben darf, nur chmod -x reichte bei den ersten Test nichts da er den stream nicht schreiben konnte/durfte!

    MfG

    --- [2019-09-15 20:13 CEST] Automatisch zusammengeführter Beitrag ---

    Hab nu nen error bekommen:

    Using local playlist: Kodi.m3u
    Traceback (most recent call last):
    File "rec.py", line 129, in <module>
    if hasPlaylist and getStreamSelection():
    File "rec.py", line 60, in getStreamSelection
    data = playlistFile.readlines()
    File "/usr/lib/python3.5/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2064: ordinal not in range(128)

  8. #33

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    UTF-8 ?

    Versuch mal die Zeile 60 wie folgt zu ändern:
    Code (Python):
    1. playlistFile = open(PLAYLIST_FILE, "r")
    zu

    Code (Python):
    1. playlistFile = open(PLAYLIST_FILE, "r", encoding='utf-8')


    Hier der komplett geänderte Code, alle Lese und Schreibfunktionen nutzen "utf-8":

    Name des Skripts (muss beibehalten werden):
    rec.py

    Spoiler: 

    Code:
    1. #!/usr/bin/env python3
    2. import sys
    3. import time
    4. import glob
    5. import subprocess
    6. import os.path
    7. import os
    8.  
    9. import pycurl
    10.  
    11. USE_AT = True
    12. PLAYLIST_URL = ".m3u8"
    13. USER_AGENT = "Your custom useragent"
    14. FFMPEG_DIRECTORY = 'ffmpeg'  # OR PATH: /home/username/path_to_ffmpeg/./ffmpeg OR leave 'ffmpeg' for general ffmpeg usage from system
    15. #FFMPEG_DIRECTORY = '/home/username/ffmpeg_4.1.4-1+b2_amd64/./ffmpeg' # example
    16.  
    17. APP_FOLDER = os.getcwd()
    18.  
    19. PLAYLIST_FILE = "streamTempSave.m3u8" # This is just a temporary storage for the downloaded playlist, but this file wont be removed by itself
    20. PLAYLIST_DATA = ""
    21. PLAYLIST_CHANNELS = {}
    22. RECORDING_NAME = ""
    23. RECORDING_CHANNEL_NAME = ""
    24. RECORDING_CHANNEL_URL = ""
    25. RECORDING_TIME = 0
    26. RECORDING_DURATION = 0
    27.  
    28. def downloadPlaylist(downloadURL):
    29.     playlistFile = open(PLAYLIST_FILE, 'w', encoding='utf-8')
    30.  
    31.     print('Starting download of URI: \'%s\'\n' % downloadURL)
    32.     c = pycurl.Curl()
    33.     c.setopt(pycurl.URL, downloadURL)
    34.     c.setopt(pycurl.USERAGENT, USER_AGENT)
    35.     c.setopt(pycurl.VERBOSE, False)
    36.     c.setopt(pycurl.ENCODING, 'utf-8')
    37.     c.setopt(pycurl.WRITEDATA, playlistFile)
    38.     c.setopt(pycurl.NOPROGRESS, True)
    39.     c.setopt(pycurl.TIMEOUT, 30)
    40.  
    41.     try:
    42.         c.perform()
    43.         print("\nSuccessfully downloaded playlist.\n")
    44.         playlistFile.close()
    45.         c.close()
    46.         return True
    47.     except Exception as error:
    48.         playlistFile.close()
    49.         c.close()
    50.         print("Encountered an error:")
    51.         raise error
    52.     return False
    53.  
    54.  
    55.  
    56. def getStreamSelection():
    57.     global PLAYLIST_CHANNELS, RECORDING_CHANNEL_NAME, RECORDING_CHANNEL_URL
    58.  
    59.     playlistFile = open(PLAYLIST_FILE, "r", encoding="utf-8")
    60.     data = playlistFile.readlines()
    61.  
    62.     currentChannel = None
    63.     for line in data:
    64.         if line.startswith('#EXTINF:'):
    65.             currentChannel = line.split(',',2)[1].rstrip().rstrip('"').replace('tvg-name="', '')
    66.             if line.find('radio="true"') != -1:
    67.                 currentChannel += ' (Radio)'
    68.         elif (currentChannel != None and line.startswith('http')):
    69.             PLAYLIST_CHANNELS[currentChannel] = line
    70.             currentChannel = None
    71.  
    72.     sortedChannels = sorted(PLAYLIST_CHANNELS.keys())
    73.  
    74.     print("\nChannel selection:")
    75.     for index, channel in enumerate(sortedChannels):
    76.         print("%2d - %s" % (index, channel))
    77.  
    78.     print("x - Exit")
    79.  
    80.     print("\n")
    81.  
    82.     while True:
    83.         channelNum = input("\nInput channel number for grabbing: ")
    84.         if channelNum.lower() == "x":
    85.             exit(0)
    86.         else:
    87.             try:
    88.                 RECORDING_CHANNEL_URL = PLAYLIST_CHANNELS[sortedChannels[int(channelNum)]].rstrip()
    89.                 RECORDING_CHANNEL_NAME = sortedChannels[int(channelNum)]
    90.  
    91.                 print("Selected recording channel: %s" % (sortedChannels[int(channelNum)]))
    92.                 isValidSelection = input('Is the channel correct Y/N? ')
    93.                 if isValidSelection.lower() == "y":
    94.                     return True
    95.                 else:
    96.                     continue
    97.  
    98.             except Exception:
    99.                 print('Wrong channel selection. Enter a channel number or "x" to exit.')
    100.                 continue
    101.             break
    102.  
    103.  
    104. if __name__ == "__main__":
    105.     hasPlaylist = False
    106.     ISWEBDL = False
    107.     if len(sys.argv) == 1:
    108.         if downloadPlaylist(PLAYLIST_URL):
    109.             hasPlaylist = True
    110.             ISWEBDL = True
    111.             print("Playlist succesfully downloaded.\n")
    112.         else:
    113.             print('Cannot download playlist "%s"' %(PLAYLIST_URL))
    114.             exit(1)
    115.     else:
    116.         for opt in sys.argv:
    117.             if opt.startswith('-local'):
    118.                 playlistName = opt.replace('-local', '', 1)
    119.                 if os.path.exists(playlistName):
    120.                     print('Using local playlist: %s' % (playlistName))
    121.                     PLAYLIST_FILE = playlistName
    122.                     hasPlaylist = True
    123.                     ISWEBDL = False
    124.                 else:
    125.                     print('Playlist not found using name "%s": ' %(playlistName))
    126.                     exit(1)
    127.  
    128.  
    129.     if hasPlaylist and getStreamSelection():
    130.         print('\nIt\'s time to enter the date and time for the recording:')
    131.         while True:
    132.             while True:
    133.                 recordDate = input('\nEnter record date for recording, in format day.month.year, for example: 7.8.2019 or "x" to cancel, enter nothing for todays date.\n')
    134.                 if recordDate.lower() == 'x':
    135.                     print("Cancelled")
    136.                     exit(1)
    137.  
    138.                 elif len(recordDate) == 0:
    139.                     timeNow = time.gmtime()
    140.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    141.                     recordDay = timeNow.tm_mday
    142.                     recordMonth = timeNow.tm_mon
    143.                     recordYear = timeNow.tm_year
    144.  
    145.                     print("Record date: %02d.%02d.%d " %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year))
    146.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    147.                         continue
    148.                     break
    149.  
    150.                 elif recordDate.count('.') == 2:
    151.                     recordDay, recordMonth, recordYear = map(int, recordDate.split('.', 3))
    152.                     timeNow = time.gmtime()
    153.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    154.  
    155.                     try:
    156.                         timestampRecord = time.strptime("%d.%d.%d 00:00:00" %(recordDay, recordMonth, recordYear), "%d.%m.%Y %H:%M:%S")
    157.                     except ValueError:
    158.                         print('Date input does not match, use day.month.year as: 7.8.2019')
    159.                         continue
    160.  
    161.                     if time.mktime(timestampNow) > time.mktime(timestampRecord):
    162.                         print("Date is in the past. Repeat input.")
    163.                     else:
    164.                         print("Record date: %02d.%02d.%d " %(recordDay, recordMonth, recordYear))
    165.  
    166.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    167.                         continue
    168.                     break
    169.                 else:
    170.                     print("Invalid date input.")
    171.                     continue
    172.  
    173.             while True:
    174.                 recordTime = input('\nEnter time to start recording, in format hour:minute, for example: 14:00 for 14 o\'clock, "x" to cancel\n')
    175.                 if recordTime.lower() == 'x':
    176.                     print("Cancelled")
    177.                     exit(1)
    178.                 elif recordTime.find(':') != -1:
    179.                     recordHour, recordMinute = map(int, recordTime.split(':', 2))
    180.                     print("Record time: %02d:%02d " %(recordHour, recordMinute))
    181.  
    182.                     timeNow = time.time()
    183.                     timestampRecord = time.strptime("%d.%d.%d %d:%d:00" %(recordDay, recordMonth, recordYear, recordHour, recordMinute), "%d.%m.%Y %H:%M:%S")
    184.  
    185.  
    186.                     if (timeNow > time.mktime(timestampRecord)):
    187.                         print("Time is in the past. Repeat input.")
    188.                         continue
    189.  
    190.                     if input("Is the record time correct, Y/N ? ").lower() != 'y':
    191.                         continue
    192.  
    193.                     RECORDING_TIME = time.mktime(timestampRecord)
    194.                     break
    195.                 else:
    196.                     print("Invald time input.")
    197.                     continue
    198.  
    199.             while True:
    200.                 recordDuration = input('\nEnter duration in minutes to record. For example 90 to capture 1 1/2 hours, "x" to cancel\n')
    201.                 if recordDuration.lower() == 'x':
    202.                     print("Cancelled")
    203.                     exit(1)
    204.                 elif int(recordDuration) < 0:
    205.                     print("Negative recording duration, enter 30 for 30 minutes.")
    206.                     continue
    207.  
    208.                 print("Record duration: %d minutes " %(int(recordDuration)))
    209.  
    210.                 if input("Is the record time correct, Y/N ? ").lower() != 'y':
    211.                     continue
    212.  
    213.                 RECORDING_DURATION = int(recordDuration)
    214.                 break
    215.  
    216.  
    217.             while True:
    218.                 RECORDING_NAME = input('\nEnter name for the recording file. Enter "x" to cancel\n')
    219.                 if recordDuration.lower() == 'x':
    220.                     print("Cancelled")
    221.                     exit(1)
    222.  
    223.                 print("Record name: %s" % (RECORDING_NAME))
    224.                 if input("Is the record name correct, Y/N ? ").lower() != 'y':
    225.                     continue
    226.  
    227.                 break
    228.  
    229.  
    230.  
    231.             print("\nWhat will be done?\nRecording channel \"%s\"." %(RECORDING_CHANNEL_NAME))
    232.             print("On %s at %s o'clock for %d minutes.\nRecording to file: \"%s\"" %(time.strftime("%d.%m.%Y", time.localtime(RECORDING_TIME)), time.strftime("%H:%M:%S", time.localtime(RECORDING_TIME)), RECORDING_DURATION, RECORDING_NAME))
    233.  
    234.             confirm = input("\nAre all information correct, Y/N? ")
    235.             if confirm.lower() != 'y':
    236.                 continue
    237.  
    238.             scheduleFileName = "%d.rec" %(time.time())
    239.             with open(scheduleFileName, 'w', encoding='utf-8') as scheduleFile:
    240.                 scheduleFile.write("%d;%d;%s;%s\n" % (RECORDING_TIME, RECORDING_DURATION, RECORDING_CHANNEL_NAME, RECORDING_NAME))
    241.  
    242.                 if USE_AT:
    243.                     if not ISWEBDL:
    244.                         scheduleCommand = 'echo "python3 %s/rec.py -ldl%s -pf%s" | at -M %s' % (APP_FOLDER, scheduleFileName, PLAYLIST_FILE, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    245.                     else:
    246.                         scheduleCommand = 'echo "python3 %s/rec.py -dl%s" | at -M %s' % (APP_FOLDER, scheduleFileName, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    247.                     subprocess.Popen(scheduleCommand, shell=True)
    248.                     print("Scheduled task.\nBye bye.")
    249.                     exit(1)
    250.  
    251.                 break
    252.  
    253.             print('Error writing schedule file for recording job.')
    254.  
    255.     else:
    256.         hasPlaylist = False
    257.         for opt in sys.argv:
    258.             if opt.startswith('-dl'):
    259.                 if downloadPlaylist(PLAYLIST_URL):
    260.                     hasPlaylist = True
    261.                     print("Playlist succesfully downloaded.\n")
    262.                 else:
    263.                     print("Error downloading playlist from \"%s\".\nExiting." %(PLAYLIST_URL))
    264.                     exit(1)
    265.             elif opt.startswith('-pf'):
    266.                 playlistName = opt.replace('-pf', '', 1)
    267.                 if os.path.exists(playlistName):
    268.                     print('Using local playlist: %s' %(playlistName))
    269.                     PLAYLIST_FILE = playlistName
    270.                 else:
    271.                     print('Playlist not found using name "%s": ' % (playlistName))
    272.                     exit(1)
    273.  
    274.  
    275.         for opt in sys.argv:
    276.             if opt.startswith('-dl'):
    277.                 with open(PLAYLIST_FILE, "r", encoding='utf-8') as playlistFile:
    278.                     data = playlistFile.readlines()
    279.  
    280.                     currentChannel = None
    281.                     for line in data:
    282.                         currentChannel = line.split(',',2)[1].rstrip().rstrip('"').replace('tvg-name="', '')
    283.                         if line.find('radio="true"') != -1:
    284.                             currentChannel += ' (Radio)'
    285.                         elif (currentChannel != None and line.startswith('http')):
    286.                             PLAYLIST_CHANNELS[currentChannel] = line.rstrip()
    287.                             currentChannel = None
    288.  
    289.                     scheduleFileName = opt.replace('-dl', '', 1)
    290.             elif opt.startswith('-ldl'):
    291.                 hasPlaylist = False
    292.                 for subopt in sys.argv:
    293.                     if subopt.startswith('-pf'):
    294.                         PLAYLIST_FILE = subopt.replace('-pf', '', 1)
    295.                         hasPlaylist = True
    296.                         break
    297.  
    298.                 with open(PLAYLIST_FILE, "r", encoding='utf-8') as playlistFile:
    299.                     data = playlistFile.readlines()
    300.  
    301.                     currentChannel = None
    302.                     for line in data:
    303.                         if line.startswith('#EXTINF:'):
    304.                             currentChannel = line.split(',',2)[1].rstrip().rstrip('"').replace('tvg-name="', '')
    305.                             if line.find('radio="true"') != -1:
    306.                                 currentChannel += ' (Radio)'
    307.                         elif (currentChannel != None and line.startswith('http')):
    308.                             PLAYLIST_CHANNELS[currentChannel] = line.rstrip()
    309.                             currentChannel = None
    310.  
    311.                 scheduleFileName = opt.replace('-ldl', '', 1)
    312.  
    313.         scheduleFile = None
    314.         if os.path.exists(scheduleFileName):
    315.             scheduleData = None
    316.  
    317.             with open(scheduleFileName, "r", encoding='utf-8') as scheduleFile:
    318.                 scheduleData = scheduleFile.read().rstrip().split(';', 4)
    319.  
    320.             if scheduleData != None:
    321.                 try:
    322.                     channelURL = PLAYLIST_CHANNELS[scheduleData[2]]
    323.                     if scheduleData[2].find(' (Radio)') != -1:
    324.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 '%s.mp3'" %(USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    325.                     else:
    326.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 -vc:copy -o '%s.mkv'" % (USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    327.                     subprocess.Popen(commandString, shell=True)
    328.                 except ValueError as error:
    329.                     print('No channel information found.')
    330.                     raise error
    331.  
    Geändert von theSplit (16.09.19 um 07:05 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  9. #34
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Moin,

    auf 2 Kisten getestet, bei einer schreibter wieder:

    Code (Text):
    1. Traceback (most recent call last):
    2.   File "rec.py", line 129, in <module>
    3.     if hasPlaylist and getStreamSelection():
    4.   File "rec.py", line 76, in getStreamSelection
    5.     print("%2d - %s" % (index, channel))
    6. UnicodeEncodeError: 'ascii' codec can't encode character '\xdc' in position 15: ordinal not in range(128)
    und in der liste kommter mit diesem eintrag nicht klar:
    Code (Text):
    1.  
    2. #EXTINF:-1 tvg-name="NDR 90,3" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/ndr903.png",NDR 90.3
    3. [url]http://ndr-ndr903-hamburg.cast.addradio.de/ndr/ndr903/hamburg/mp3/128/stream.mp3[/url]
    da kommt dann diese Anzeigen:

    Code (Text):
    1. 11 - 3" group-title="Deutschland" radio="true" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/radio/ndr903.png (Radio)
    das komische ist auch das er die liste wohl nicht komplett von oben abarbeitet? 0o Oder Überspringt das script die Streams die Offline sind? Im mom werden bei einer kiste gute 430(!) gelistet bei der anderen kiste kackt er bei stream 18 schon ab, siehe oben.

    MfG

    edit2:

    Nu kommt nichts mehr wenn er die Liste Online holen will:

    Code (Text):
    1.  
    2. TypeError: write() argument must be str, not bytes
    3. Encountered an error:
    4. Traceback (most recent call last):
    5.   File "rec.py", line 108, in <module>
    6.     if downloadPlaylist(PLAYLIST_URL):
    7.   File "rec.py", line 51, in downloadPlaylist
    8.     raise error
    9.   File "rec.py", line 42, in downloadPlaylist
    10.     c.perform()
    11. pycurl.error: (23, 'Failed writing body (0 != 5576)')
    12.  
    Geändert von DukeMan999 (16.09.19 um 09:34 Uhr)

  10. #35

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    @DukeMan999: Okay..

    1) die Channel Namensauflösung wird nun aus dem "tvg-name" berücksichtigt, so fern vorhanden
    2) downloadPlaylists (Curl) testweise auf Binär umgestellt und Encoding der Datei entfernt, dass könnte die UTF-8 Probleme beheben.
    3) "bytes" wo sinnvoll damit bei der Channelnamen Auswahl kein Fehler geworfen wird.

    Code:
    1. #!/usr/bin/env python3
    2. import sys
    3. import time
    4. import glob
    5. import subprocess
    6. import os.path
    7. import os
    8. import re
    9.  
    10. import pycurl
    11.  
    12. USE_AT = True
    13. PLAYLIST_URL = ".m3u8"
    14. USER_AGENT = "Your custom useragent"
    15. FFMPEG_DIRECTORY = 'ffmpeg'  # OR PATH: /home/username/path_to_ffmpeg/./ffmpeg OR leave 'ffmpeg' for general ffmpeg usage from system
    16. #FFMPEG_DIRECTORY = '/home/username/ffmpeg_4.1.4-1+b2_amd64/./ffmpeg' # example
    17.  
    18. APP_FOLDER = os.getcwd()
    19.  
    20. PLAYLIST_FILE = "streamTempSave.m3u8" # This is just a temporary storage for the downloaded playlist, but this file wont be removed by itself
    21. PLAYLIST_DATA = ""
    22. PLAYLIST_CHANNELS = {}
    23. RECORDING_NAME = ""
    24. RECORDING_CHANNEL_NAME = ""
    25. RECORDING_CHANNEL_URL = ""
    26. RECORDING_TIME = 0
    27. RECORDING_DURATION = 0
    28.  
    29. def downloadPlaylist(downloadURL):
    30.     playlistFile = open(PLAYLIST_FILE, 'wb')
    31.  
    32.     print('Starting download of URI: \'%s\'\n' % downloadURL)
    33.     c = pycurl.Curl()
    34.     c.setopt(pycurl.URL, downloadURL)
    35.     c.setopt(pycurl.USERAGENT, USER_AGENT)
    36.     c.setopt(pycurl.VERBOSE, False)
    37.     c.setopt(pycurl.ENCODING, 'utf-8')
    38.     c.setopt(pycurl.WRITEDATA, playlistFile)
    39.     c.setopt(pycurl.NOPROGRESS, True)
    40.     c.setopt(pycurl.TIMEOUT, 30)
    41.  
    42.     try:
    43.         c.perform()
    44.         print("\nSuccessfully downloaded playlist.\n")
    45.         playlistFile.close()
    46.         c.close()
    47.         return True
    48.     except Exception as error:
    49.         playlistFile.close()
    50.         c.close()
    51.         print("Encountered an error:")
    52.         raise error
    53.     return False
    54.  
    55.  
    56.  
    57. def getStreamSelection():
    58.     global PLAYLIST_CHANNELS, RECORDING_CHANNEL_NAME, RECORDING_CHANNEL_URL
    59.  
    60.     playlistFile = open(PLAYLIST_FILE, "r", encoding="utf-8")
    61.     data = playlistFile.readlines()
    62.  
    63.     currentChannel = None
    64.     for line in data:
    65.         if line.startswith('#EXTINF:'):
    66.             try:
    67.                 currentChannel = list(re.findall(r'tvg-name\=\"(.[^"]*)', line))[0]
    68.             except:
    69.                 currentChannel = line.split(',',2)[1].rstrip()
    70.             if line.find('radio="true"') != -1:
    71.                 currentChannel += ' (Radio)'
    72.         elif (currentChannel != None and line.startswith('http')):
    73.             PLAYLIST_CHANNELS[currentChannel] = bytes(line, 'utf-8').decode('utf-8', 'ignore').rstrip()
    74.             currentChannel = None
    75.  
    76.     sortedChannels = sorted(PLAYLIST_CHANNELS.keys())
    77.  
    78.     print("\nChannel selection:")
    79.     for index, channel in enumerate(sortedChannels):
    80.         print("%2d - %s" % (index, channel))
    81.  
    82.     print("x - Exit")
    83.  
    84.     print("\n")
    85.  
    86.     while True:
    87.         channelNum = input("\nInput channel number for grabbing: ")
    88.         if channelNum.lower() == "x":
    89.             exit(0)
    90.         else:
    91.             try:
    92.                 RECORDING_CHANNEL_URL = PLAYLIST_CHANNELS[sortedChannels[int(channelNum)]].rstrip()
    93.                 RECORDING_CHANNEL_NAME = sortedChannels[int(channelNum)]
    94.  
    95.                 print("Selected recording channel: %s" % (sortedChannels[int(channelNum)]))
    96.                 isValidSelection = input('Is the channel correct Y/N? ')
    97.                 if isValidSelection.lower() == "y":
    98.                     return True
    99.                 else:
    100.                     continue
    101.  
    102.             except Exception:
    103.                 print('Wrong channel selection. Enter a channel number or "x" to exit.')
    104.                 continue
    105.             break
    106.  
    107.  
    108. if __name__ == "__main__":
    109.     hasPlaylist = False
    110.     ISWEBDL = False
    111.     if len(sys.argv) == 1:
    112.         if downloadPlaylist(PLAYLIST_URL):
    113.             hasPlaylist = True
    114.             ISWEBDL = True
    115.             print("Playlist succesfully downloaded.\n")
    116.         else:
    117.             print('Cannot download playlist "%s"' %(PLAYLIST_URL))
    118.             exit(1)
    119.     else:
    120.         for opt in sys.argv:
    121.             if opt.startswith('-local'):
    122.                 playlistName = opt.replace('-local', '', 1)
    123.                 if os.path.exists(playlistName):
    124.                     print('Using local playlist: %s' % (playlistName))
    125.                     PLAYLIST_FILE = playlistName
    126.                     hasPlaylist = True
    127.                     ISWEBDL = False
    128.                 else:
    129.                     print('Playlist not found using name "%s": ' %(playlistName))
    130.                     exit(1)
    131.  
    132.  
    133.     if hasPlaylist and getStreamSelection():
    134.         print('\nIt\'s time to enter the date and time for the recording:')
    135.         while True:
    136.             while True:
    137.                 recordDate = input('\nEnter record date for recording, in format day.month.year, for example: 7.8.2019 or "x" to cancel, enter nothing for todays date.\n')
    138.                 if recordDate.lower() == 'x':
    139.                     print("Cancelled")
    140.                     exit(1)
    141.  
    142.                 elif len(recordDate) == 0:
    143.                     timeNow = time.gmtime()
    144.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    145.                     recordDay = timeNow.tm_mday
    146.                     recordMonth = timeNow.tm_mon
    147.                     recordYear = timeNow.tm_year
    148.  
    149.                     print("Record date: %02d.%02d.%d " %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year))
    150.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    151.                         continue
    152.                     break
    153.  
    154.                 elif recordDate.count('.') == 2:
    155.                     recordDay, recordMonth, recordYear = map(int, recordDate.split('.', 3))
    156.                     timeNow = time.gmtime()
    157.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    158.  
    159.                     try:
    160.                         timestampRecord = time.strptime("%d.%d.%d 00:00:00" %(recordDay, recordMonth, recordYear), "%d.%m.%Y %H:%M:%S")
    161.                     except ValueError:
    162.                         print('Date input does not match, use day.month.year as: 7.8.2019')
    163.                         continue
    164.  
    165.                     if time.mktime(timestampNow) > time.mktime(timestampRecord):
    166.                         print("Date is in the past. Repeat input.")
    167.                     else:
    168.                         print("Record date: %02d.%02d.%d " %(recordDay, recordMonth, recordYear))
    169.  
    170.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    171.                         continue
    172.                     break
    173.                 else:
    174.                     print("Invalid date input.")
    175.                     continue
    176.  
    177.             while True:
    178.                 recordTime = input('\nEnter time to start recording, in format hour:minute, for example: 14:00 for 14 o\'clock, "x" to cancel\n')
    179.                 if recordTime.lower() == 'x':
    180.                     print("Cancelled")
    181.                     exit(1)
    182.                 elif recordTime.find(':') != -1:
    183.                     recordHour, recordMinute = map(int, recordTime.split(':', 2))
    184.                     print("Record time: %02d:%02d " %(recordHour, recordMinute))
    185.  
    186.                     timeNow = time.time()
    187.                     timestampRecord = time.strptime("%d.%d.%d %d:%d:00" %(recordDay, recordMonth, recordYear, recordHour, recordMinute), "%d.%m.%Y %H:%M:%S")
    188.  
    189.  
    190.                     if (timeNow > time.mktime(timestampRecord)):
    191.                         print("Time is in the past. Repeat input.")
    192.                         continue
    193.  
    194.                     if input("Is the record time correct, Y/N ? ").lower() != 'y':
    195.                         continue
    196.  
    197.                     RECORDING_TIME = time.mktime(timestampRecord)
    198.                     break
    199.                 else:
    200.                     print("Invald time input.")
    201.                     continue
    202.  
    203.             while True:
    204.                 recordDuration = input('\nEnter duration in minutes to record. For example 90 to capture 1 1/2 hours, "x" to cancel\n')
    205.                 if recordDuration.lower() == 'x':
    206.                     print("Cancelled")
    207.                     exit(1)
    208.                 elif int(recordDuration) < 0:
    209.                     print("Negative recording duration, enter 30 for 30 minutes.")
    210.                     continue
    211.  
    212.                 print("Record duration: %d minutes " %(int(recordDuration)))
    213.  
    214.                 if input("Is the record time correct, Y/N ? ").lower() != 'y':
    215.                     continue
    216.  
    217.                 RECORDING_DURATION = int(recordDuration)
    218.                 break
    219.  
    220.  
    221.             while True:
    222.                 RECORDING_NAME = input('\nEnter name for the recording file. Enter "x" to cancel\n')
    223.                 if recordDuration.lower() == 'x':
    224.                     print("Cancelled")
    225.                     exit(1)
    226.  
    227.                 print("Record name: %s" % (RECORDING_NAME))
    228.                 if input("Is the record name correct, Y/N ? ").lower() != 'y':
    229.                     continue
    230.  
    231.                 break
    232.  
    233.  
    234.  
    235.             print("\nWhat will be done?\nRecording channel \"%s\"." %(RECORDING_CHANNEL_NAME))
    236.             print("On %s at %s o'clock for %d minutes.\nRecording to file: \"%s\"" %(time.strftime("%d.%m.%Y", time.localtime(RECORDING_TIME)), time.strftime("%H:%M:%S", time.localtime(RECORDING_TIME)), RECORDING_DURATION, RECORDING_NAME))
    237.  
    238.             confirm = input("\nAre all information correct, Y/N? ")
    239.             if confirm.lower() != 'y':
    240.                 continue
    241.  
    242.             scheduleFileName = "%d.rec" %(time.time())
    243.             with open(scheduleFileName, 'w', encoding='utf-8') as scheduleFile:
    244.                 scheduleFile.write("%d;%d;%s;%s\n" % (RECORDING_TIME, RECORDING_DURATION, RECORDING_CHANNEL_NAME, RECORDING_NAME))
    245.  
    246.                 if USE_AT:
    247.                     if not ISWEBDL:
    248.                         scheduleCommand = 'echo "python3 %s/rec.py -ldl%s -pf%s" | at -M %s' % (APP_FOLDER, scheduleFileName, PLAYLIST_FILE, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    249.                     else:
    250.                         scheduleCommand = 'echo "python3 %s/rec.py -dl%s" | at -M %s' % (APP_FOLDER, scheduleFileName, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    251.                     subprocess.Popen(scheduleCommand, shell=True)
    252.                     print("Scheduled task.\nBye bye.")
    253.                     exit(1)
    254.  
    255.                 break
    256.  
    257.             print('Error writing schedule file for recording job.')
    258.  
    259.     else:
    260.         hasPlaylist = False
    261.         for opt in sys.argv:
    262.             if opt.startswith('-dl'):
    263.                 if downloadPlaylist(PLAYLIST_URL):
    264.                     hasPlaylist = True
    265.                     print("Playlist succesfully downloaded.\n")
    266.                 else:
    267.                     print("Error downloading playlist from \"%s\".\nExiting." %(PLAYLIST_URL))
    268.                     exit(1)
    269.             elif opt.startswith('-pf'):
    270.                 playlistName = opt.replace('-pf', '', 1)
    271.                 if os.path.exists(playlistName):
    272.                     print('Using local playlist: %s' %(playlistName))
    273.                     PLAYLIST_FILE = playlistName
    274.                 else:
    275.                     print('Playlist not found using name "%s": ' % (playlistName))
    276.                     exit(1)
    277.  
    278.  
    279.         for opt in sys.argv:
    280.             if opt.startswith('-dl'):
    281.                 with open(PLAYLIST_FILE, "r", encoding='utf-8') as playlistFile:
    282.                     data = playlistFile.readlines()
    283.  
    284.                     currentChannel = None
    285.                     for line in data:
    286.                         try:
    287.                             currentChannel = list(re.findall(r'tvg-name\=\"(.[^"]*)', line))[0]
    288.                         except:
    289.                             currentChannel = line.split(',',2)[1].rstrip()
    290.  
    291.                         if line.find('radio="true"') != -1:
    292.                             currentChannel += ' (Radio)'
    293.                         elif (currentChannel != None and line.startswith('http')):
    294.                             PLAYLIST_CHANNELS[currentChannel] = bytes(line, 'utf-8').decode('utf-8', 'ignore').rstrip()
    295.                             currentChannel = None
    296.  
    297.                     scheduleFileName = opt.replace('-dl', '', 1)
    298.             elif opt.startswith('-ldl'):
    299.                 hasPlaylist = False
    300.                 for subopt in sys.argv:
    301.                     if subopt.startswith('-pf'):
    302.                         PLAYLIST_FILE = subopt.replace('-pf', '', 1)
    303.                         hasPlaylist = True
    304.                         break
    305.  
    306.                 with open(PLAYLIST_FILE, "r", encoding='utf-8') as playlistFile:
    307.                     data = playlistFile.readlines()
    308.  
    309.                     currentChannel = None
    310.                     for line in data:
    311.                         if line.startswith('#EXTINF:'):
    312.                             try:
    313.                                 currentChannel = list(re.findall(r'tvg-name\=\"(.[^"]*)', line))[0]
    314.                             except:
    315.                                 currentChannel = line.split(',',2)[1].rstrip()
    316.  
    317.                             if line.find('radio="true"') != -1:
    318.                                 currentChannel += ' (Radio)'
    319.                         elif (currentChannel != None and line.startswith('http')):
    320.                             PLAYLIST_CHANNELS[currentChannel] = bytes(line, 'utf-8').decode('utf-8', 'ignore').rstrip()
    321.                             currentChannel = None
    322.  
    323.                 sortedChannels = sorted(PLAYLIST_CHANNELS.keys())
    324.                 scheduleFileName = opt.replace('-ldl', '', 1)
    325.  
    326.         scheduleFile = None
    327.         if os.path.exists(scheduleFileName):
    328.             scheduleData = None
    329.  
    330.             with open(scheduleFileName, "r", encoding='utf-8') as scheduleFile:
    331.                 scheduleData = scheduleFile.read().rstrip().split(';', 4)
    332.  
    333.             if scheduleData != None:
    334.                 try:
    335.                     channelURL = PLAYLIST_CHANNELS[scheduleData[2]]
    336.                     if scheduleData[2].find(' (Radio)') != -1:
    337.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 '%s.mp3'" %(USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    338.                     else:
    339.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 -vc:copy -o '%s.mkv'" % (USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    340.                     subprocess.Popen(commandString, shell=True)
    341.                 except ValueError as error:
    342.                     print('No channel information found.')
    343.                     raise error
    344.  
    Geändert von theSplit (16.09.19 um 12:06 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  11. #36
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Bei kiste 1 das gleiche Prob wieder mit localer Liste:

    Code (Text):
    1. Traceback (most recent call last):
    2.   File "rec.py", line 133, in <module>
    3.     if hasPlaylist and getStreamSelection():
    4.   File "rec.py", line 80, in getStreamSelection
    5.     print("%2d - %s" % (index, channel))
    6. UnicodeEncodeError: 'ascii' codec can't encode character '\xdc' in position 15: ordinal not in range(128)
    Python 3.5.3 (default, Sep 27 2018, 17:25:39)
    [GCC 6.3.0 20170516] on linux


    keine probs die liste online zu holen.

    Kiste 2:

    Keine Probs die Liste local und Online zu holen und zu verarbeiten.

    Und dort ist python nen stückel älter:
    Python 3.5.2 (default, Nov 12 2018, 13:43:14)
    [GCC 5.4.0 20160609] on linux

    ka warum kiste 1 probs hat die Liste local zu verarbeiten 0o

    MfG

    edit2:

    so bei kiste 3 gibts auch keine Probs weder local noch online die liste zu verarbeiten auch wenn dort python älter ist:
    Python 3.5.2 (default, Nov 12 2018, 13:43:14)
    [GCC 5.4.0 20160609] on linux

    MfG
    Geändert von DukeMan999 (16.09.19 um 16:36 Uhr)

  12. #37

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    @DukeMan999: Also noch ein Versuch...

    Wenn dass das Problem nicht behebt, schick mir mal bitte die lokale Playlist die verarbeitet werden soll. (am besten per PN). Die, die auf Kiste 1 nicht läuft.

    Spoiler: 

    Code:
    1. #!/usr/bin/env python3
    2. import sys
    3. import time
    4. import glob
    5. import subprocess
    6. import os.path
    7. import os
    8. import re
    9.  
    10. import pycurl
    11.  
    12. USE_AT = True
    13. PLAYLIST_URL = ".m3u8"
    14. USER_AGENT = "Your custom useragent"
    15. FFMPEG_DIRECTORY = 'ffmpeg'  # OR PATH: /home/username/path_to_ffmpeg/./ffmpeg OR leave 'ffmpeg' for general ffmpeg usage from system
    16. #FFMPEG_DIRECTORY = '/home/username/ffmpeg_4.1.4-1+b2_amd64/./ffmpeg' # example
    17.  
    18. APP_FOLDER = os.getcwd()
    19.  
    20. PLAYLIST_FILE = "streamTempSave.m3u8" # This is just a temporary storage for the downloaded playlist, but this file wont be removed by itself
    21. PLAYLIST_DATA = ""
    22. PLAYLIST_CHANNELS = {}
    23. RECORDING_NAME = ""
    24. RECORDING_CHANNEL_NAME = ""
    25. RECORDING_CHANNEL_URL = ""
    26. RECORDING_TIME = 0
    27. RECORDING_DURATION = 0
    28.  
    29. def downloadPlaylist(downloadURL):
    30.     playlistFile = open(PLAYLIST_FILE, 'wb')
    31.  
    32.     print('Starting download of URI: \'%s\'\n' % downloadURL)
    33.     c = pycurl.Curl()
    34.     c.setopt(pycurl.URL, downloadURL)
    35.     c.setopt(pycurl.USERAGENT, USER_AGENT)
    36.     c.setopt(pycurl.VERBOSE, False)
    37.     c.setopt(pycurl.ENCODING, 'utf-8')
    38.     c.setopt(pycurl.WRITEDATA, playlistFile)
    39.     c.setopt(pycurl.NOPROGRESS, True)
    40.     c.setopt(pycurl.TIMEOUT, 30)
    41.  
    42.     try:
    43.         c.perform()
    44.         print("\nSuccessfully downloaded playlist.\n")
    45.         playlistFile.close()
    46.         c.close()
    47.         return True
    48.     except Exception as error:
    49.         playlistFile.close()
    50.         c.close()
    51.         print("Encountered an error:")
    52.         raise error
    53.     return False
    54.  
    55.  
    56.  
    57. def getStreamSelection():
    58.     global PLAYLIST_CHANNELS, RECORDING_CHANNEL_NAME, RECORDING_CHANNEL_URL
    59.  
    60.     playlistFile = open(PLAYLIST_FILE, "r", encoding="utf-8")
    61.     data = playlistFile.readlines()
    62.  
    63.     currentChannel = None
    64.     for line in data:
    65.         if line.startswith('#EXTINF:'):
    66.             try:
    67.                 currentChannel = list(re.findall(r'tvg-name\=\"(.[^"]*)', line))[0]
    68.             except:
    69.                 currentChannel = line.split(',',2)[1].rstrip()
    70.  
    71.             currentChannel = bytes(currentChannel, 'utf-8').decode('utf-8', 'ignore').rstrip()
    72.  
    73.             if line.find('radio="true"') != -1:
    74.                 currentChannel += ' (Radio)'
    75.  
    76.         elif (currentChannel != None and line.startswith('http')):
    77.             PLAYLIST_CHANNELS[currentChannel] = bytes(line, 'utf-8').decode('utf-8', 'ignore').rstrip()
    78.             currentChannel = None
    79.  
    80.     sortedChannels = sorted(PLAYLIST_CHANNELS.keys())
    81.  
    82.     print("\nChannel selection:")
    83.     for index, channel in enumerate(sortedChannels):
    84.         print("%2d - %s" % (index, channel))
    85.  
    86.     print("x - Exit")
    87.  
    88.     print("\n")
    89.  
    90.     while True:
    91.         channelNum = input("\nInput channel number for grabbing: ")
    92.         if channelNum.lower() == "x":
    93.             exit(0)
    94.         else:
    95.             try:
    96.                 RECORDING_CHANNEL_URL = PLAYLIST_CHANNELS[sortedChannels[int(channelNum)]].rstrip()
    97.                 RECORDING_CHANNEL_NAME = sortedChannels[int(channelNum)]
    98.  
    99.                 print("Selected recording channel: %s" % (sortedChannels[int(channelNum)]))
    100.                 isValidSelection = input('Is the channel correct Y/N? ')
    101.                 if isValidSelection.lower() == "y":
    102.                     return True
    103.                 else:
    104.                     continue
    105.  
    106.             except Exception:
    107.                 print('Wrong channel selection. Enter a channel number or "x" to exit.')
    108.                 continue
    109.             break
    110.  
    111.  
    112. if __name__ == "__main__":
    113.     hasPlaylist = False
    114.     ISWEBDL = False
    115.     if len(sys.argv) == 1:
    116.         if downloadPlaylist(PLAYLIST_URL):
    117.             hasPlaylist = True
    118.             ISWEBDL = True
    119.             print("Playlist succesfully downloaded.\n")
    120.         else:
    121.             print('Cannot download playlist "%s"' %(PLAYLIST_URL))
    122.             exit(1)
    123.     else:
    124.         for opt in sys.argv:
    125.             if opt.startswith('-local'):
    126.                 playlistName = opt.replace('-local', '', 1)
    127.                 if os.path.exists(playlistName):
    128.                     print('Using local playlist: %s' % (playlistName))
    129.                     PLAYLIST_FILE = playlistName
    130.                     hasPlaylist = True
    131.                     ISWEBDL = False
    132.                 else:
    133.                     print('Playlist not found using name "%s": ' %(playlistName))
    134.                     exit(1)
    135.  
    136.  
    137.     if hasPlaylist and getStreamSelection():
    138.         print('\nIt\'s time to enter the date and time for the recording:')
    139.         while True:
    140.             while True:
    141.                 recordDate = input('\nEnter record date for recording, in format day.month.year, for example: 7.8.2019 or "x" to cancel, enter nothing for todays date.\n')
    142.                 if recordDate.lower() == 'x':
    143.                     print("Cancelled")
    144.                     exit(1)
    145.  
    146.                 elif len(recordDate) == 0:
    147.                     timeNow = time.gmtime()
    148.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    149.                     recordDay = timeNow.tm_mday
    150.                     recordMonth = timeNow.tm_mon
    151.                     recordYear = timeNow.tm_year
    152.  
    153.                     print("Record date: %02d.%02d.%d " %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year))
    154.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    155.                         continue
    156.                     break
    157.  
    158.                 elif recordDate.count('.') == 2:
    159.                     recordDay, recordMonth, recordYear = map(int, recordDate.split('.', 3))
    160.                     timeNow = time.gmtime()
    161.                     timestampNow = time.strptime("%d.%d.%d 00:00:00" %(timeNow.tm_mday, timeNow.tm_mon, timeNow.tm_year), "%d.%m.%Y %H:%M:%S")
    162.  
    163.                     try:
    164.                         timestampRecord = time.strptime("%d.%d.%d 00:00:00" %(recordDay, recordMonth, recordYear), "%d.%m.%Y %H:%M:%S")
    165.                     except ValueError:
    166.                         print('Date input does not match, use day.month.year as: 7.8.2019')
    167.                         continue
    168.  
    169.                     if time.mktime(timestampNow) > time.mktime(timestampRecord):
    170.                         print("Date is in the past. Repeat input.")
    171.                     else:
    172.                         print("Record date: %02d.%02d.%d " %(recordDay, recordMonth, recordYear))
    173.  
    174.                     if input("Is the record date correct Y/N ? ").lower() != 'y':
    175.                         continue
    176.                     break
    177.                 else:
    178.                     print("Invalid date input.")
    179.                     continue
    180.  
    181.             while True:
    182.                 recordTime = input('\nEnter time to start recording, in format hour:minute, for example: 14:00 for 14 o\'clock, "x" to cancel\n')
    183.                 if recordTime.lower() == 'x':
    184.                     print("Cancelled")
    185.                     exit(1)
    186.                 elif recordTime.find(':') != -1:
    187.                     recordHour, recordMinute = map(int, recordTime.split(':', 2))
    188.                     print("Record time: %02d:%02d " %(recordHour, recordMinute))
    189.  
    190.                     timeNow = time.time()
    191.                     timestampRecord = time.strptime("%d.%d.%d %d:%d:00" %(recordDay, recordMonth, recordYear, recordHour, recordMinute), "%d.%m.%Y %H:%M:%S")
    192.  
    193.  
    194.                     if (timeNow > time.mktime(timestampRecord)):
    195.                         print("Time is in the past. Repeat input.")
    196.                         continue
    197.  
    198.                     if input("Is the record time correct, Y/N ? ").lower() != 'y':
    199.                         continue
    200.  
    201.                     RECORDING_TIME = time.mktime(timestampRecord)
    202.                     break
    203.                 else:
    204.                     print("Invald time input.")
    205.                     continue
    206.  
    207.             while True:
    208.                 recordDuration = input('\nEnter duration in minutes to record. For example 90 to capture 1 1/2 hours, "x" to cancel\n')
    209.                 if recordDuration.lower() == 'x':
    210.                     print("Cancelled")
    211.                     exit(1)
    212.                 elif int(recordDuration) < 0:
    213.                     print("Negative recording duration, enter 30 for 30 minutes.")
    214.                     continue
    215.  
    216.                 print("Record duration: %d minutes " %(int(recordDuration)))
    217.  
    218.                 if input("Is the record time correct, Y/N ? ").lower() != 'y':
    219.                     continue
    220.  
    221.                 RECORDING_DURATION = int(recordDuration)
    222.                 break
    223.  
    224.  
    225.             while True:
    226.                 RECORDING_NAME = input('\nEnter name for the recording file. Enter "x" to cancel\n')
    227.                 if recordDuration.lower() == 'x':
    228.                     print("Cancelled")
    229.                     exit(1)
    230.  
    231.                 print("Record name: %s" % (RECORDING_NAME))
    232.                 if input("Is the record name correct, Y/N ? ").lower() != 'y':
    233.                     continue
    234.  
    235.                 break
    236.  
    237.  
    238.  
    239.             print("\nWhat will be done?\nRecording channel \"%s\"." %(RECORDING_CHANNEL_NAME))
    240.             print("On %s at %s o'clock for %d minutes.\nRecording to file: \"%s\"" %(time.strftime("%d.%m.%Y", time.localtime(RECORDING_TIME)), time.strftime("%H:%M:%S", time.localtime(RECORDING_TIME)), RECORDING_DURATION, RECORDING_NAME))
    241.  
    242.             confirm = input("\nAre all information correct, Y/N? ")
    243.             if confirm.lower() != 'y':
    244.                 continue
    245.  
    246.             scheduleFileName = "%d.rec" %(time.time())
    247.             with open(scheduleFileName, 'w', encoding='utf-8') as scheduleFile:
    248.                 scheduleFile.write("%d;%d;%s;%s\n" % (RECORDING_TIME, RECORDING_DURATION, RECORDING_CHANNEL_NAME, RECORDING_NAME))
    249.  
    250.                 if USE_AT:
    251.                     if not ISWEBDL:
    252.                         scheduleCommand = 'echo "python3 %s/rec.py -ldl%s -pf%s" | at -M %s' % (APP_FOLDER, scheduleFileName, PLAYLIST_FILE, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    253.                     else:
    254.                         scheduleCommand = 'echo "python3 %s/rec.py -dl%s" | at -M %s' % (APP_FOLDER, scheduleFileName, time.strftime("%H:%M %d.%m.%Y", time.localtime(RECORDING_TIME)))
    255.                     subprocess.Popen(scheduleCommand, shell=True)
    256.                     print("Scheduled task.\nBye bye.")
    257.                     exit(1)
    258.  
    259.                 break
    260.  
    261.             print('Error writing schedule file for recording job.')
    262.  
    263.     else:
    264.         hasPlaylist = False
    265.         for opt in sys.argv:
    266.             if opt.startswith('-dl'):
    267.                 if downloadPlaylist(PLAYLIST_URL):
    268.                     hasPlaylist = True
    269.                     print("Playlist succesfully downloaded.\n")
    270.                 else:
    271.                     print("Error downloading playlist from \"%s\".\nExiting." %(PLAYLIST_URL))
    272.                     exit(1)
    273.             elif opt.startswith('-pf'):
    274.                 playlistName = opt.replace('-pf', '', 1)
    275.                 if os.path.exists(playlistName):
    276.                     print('Using local playlist: %s' %(playlistName))
    277.                     PLAYLIST_FILE = playlistName
    278.                 else:
    279.                     print('Playlist not found using name "%s": ' % (playlistName))
    280.                     exit(1)
    281.  
    282.  
    283.         for opt in sys.argv:
    284.             if opt.startswith('-dl'):
    285.                 with open(PLAYLIST_FILE, "r", encoding='utf-8') as playlistFile:
    286.                     data = playlistFile.readlines()
    287.  
    288.                     currentChannel = None
    289.                     for line in data:
    290.                         try:
    291.                             currentChannel = list(re.findall(r'tvg-name\=\"(.[^"]*)', line))[0]
    292.                         except:
    293.                             currentChannel = line.split(',',2)[1].rstrip()
    294.  
    295.                         currentChannel = bytes(currentChannel, 'utf-8').decode('utf-8', 'ignore').rstrip()
    296.  
    297.                         if line.find('radio="true"') != -1:
    298.                             currentChannel += ' (Radio)'
    299.  
    300.                         elif (currentChannel != None and line.startswith('http')):
    301.                             PLAYLIST_CHANNELS[currentChannel] = bytes(line, 'utf-8').decode('utf-8', 'ignore').rstrip()
    302.                             currentChannel = None
    303.  
    304.                     scheduleFileName = opt.replace('-dl', '', 1)
    305.             elif opt.startswith('-ldl'):
    306.                 hasPlaylist = False
    307.                 for subopt in sys.argv:
    308.                     if subopt.startswith('-pf'):
    309.                         PLAYLIST_FILE = subopt.replace('-pf', '', 1)
    310.                         hasPlaylist = True
    311.                         break
    312.  
    313.                 with open(PLAYLIST_FILE, "r", encoding='utf-8') as playlistFile:
    314.                     data = playlistFile.readlines()
    315.  
    316.                     currentChannel = None
    317.                     for line in data:
    318.                         if line.startswith('#EXTINF:'):
    319.                             try:
    320.                                 currentChannel = list(re.findall(r'tvg-name\=\"(.[^"]*)', line))[0]
    321.                             except:
    322.                                 currentChannel = line.split(',',2)[1].rstrip()
    323.  
    324.                             currentChannel = bytes(currentChannel, 'utf-8').decode('utf-8', 'ignore').rstrip()
    325.  
    326.                             if line.find('radio="true"') != -1:
    327.                                 currentChannel += ' (Radio)'
    328.  
    329.                         elif (currentChannel != None and line.startswith('http')):
    330.                             PLAYLIST_CHANNELS[currentChannel] = bytes(line, 'utf-8').decode('utf-8', 'ignore').rstrip()
    331.                             currentChannel = None
    332.  
    333.                 sortedChannels = sorted(PLAYLIST_CHANNELS.keys())
    334.                 scheduleFileName = opt.replace('-ldl', '', 1)
    335.  
    336.         scheduleFile = None
    337.         if os.path.exists(scheduleFileName):
    338.             scheduleData = None
    339.  
    340.             with open(scheduleFileName, "r", encoding='utf-8') as scheduleFile:
    341.                 scheduleData = scheduleFile.read().rstrip().split(';', 4)
    342.  
    343.             if scheduleData != None:
    344.                 try:
    345.                     channelURL = PLAYLIST_CHANNELS[scheduleData[2]]
    346.                     if scheduleData[2].find(' (Radio)') != -1:
    347.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 '%s.mp3'" %(USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    348.                     else:
    349.                         commandString = FFMPEG_DIRECTORY + " -user_agent \"%s\" -i '%s' -t %d:%d:00 -vc:copy -o '%s.mkv'" % (USER_AGENT, channelURL, int(scheduleData[1]) / 60, int(scheduleData[1]) % 60, scheduleData[3].rstrip())
    350.                     subprocess.Popen(commandString, shell=True)
    351.                 except ValueError as error:
    352.                     print('No channel information found.')
    353.                     raise error
    354.  
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  13. #38
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    und wieder:

    Traceback (most recent call last):
    File "rec.py", line 137, in <module>
    if hasPlaylist and getStreamSelection():
    File "rec.py", line 84, in getStreamSelection
    print("%2d - %s" % (index, channel))
    UnicodeEncodeError: 'ascii' codec can't encode character '\xdc' in position 15: ordinal not in range(128)

    ich schick dir mal die liste...

  14. #39

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    @DukeMan999: Also, deine Liste funktioniert bei mir.

    Allerdings habe ich auch """Python 3.7.4+ (default, Sep 4 2019)""" hier.

    Kannst du auf Kiste 1 mal eine neuere Python Version installieren, um zu testen ob das Abhilfe schafft?
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  15. #40
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Hmz,

    im mom nehmen keine der 3 listen einen online stream auf 0o *konfused ist*

    1568734551.rec
    in der ist
    1568744040;170;PRO 7;renn.zur.million

    das drin aber macht nichts? per "atq" wird auch nichts gelistet o0

    MfG

  16. #41

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    @DukeMan999: Ich hab den Fehler gefunden. Die Aufnahme wurde zwar gescheduled, aber bei "redownload der Playlist" wurde diese nicht korrekt eingelesen und hat einen Fehler geworfen was zum Abbruch führte.

    Die Version ist im Anhang, um nicht immer Quelltext zu posten.

    PS: Das kommt davon, wenn man die Leseroutine nicht in eine gemeinsame Funktion packt, sondern sie an 3 (!) Stellen jeweils editieren muß.

    Die anderen beiden Stellen waren korrekt.
    Angehängte Dateien Angehängte Dateien
    Geändert von theSplit (18.09.19 um 06:13 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ Bandcamp 500 +++ dwrox.net

  17. #42
    Duke Nukem Master

    (Threadstarter)

    Avatar von DukeMan999
    Registriert seit
    Jul 2013
    Beiträge
    133

    Re: VLC Stream Aufzeichnen und zwar Zeitgesteuert

    Funzt wieder auf alle kisten mit der online liste! Offline muß ich noch weiter probieren....

    MfG

    edit: Offline ist bei kiste 1 immer noch tot
    Geändert von DukeMan999 (18.09.19 um 10:21 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •