Byl vydán Nextcloud Hub 8. Představení novinek tohoto open source cloudového řešení také na YouTube. Vypíchnout lze Nextcloud AI Assistant 2.0.
Vyšlo Pharo 12.0, programovací jazyk a vývojové prostředí s řadou pokročilých vlastností. Krom tradiční nadílky oprav přináší nový systém správy ladících bodů, nový způsob definice tříd, prostor pro objekty, které nemusí procházet GC a mnoho dalšího.
Microsoft zveřejnil na GitHubu zdrojové kódy MS-DOSu 4.0 pod licencí MIT. Ve stejném repozitáři se nacházejí i před lety zveřejněné zdrojové k kódy MS-DOSu 1.25 a 2.0.
Canonical vydal (email, blog, YouTube) Ubuntu 24.04 LTS Noble Numbat. Přehled novinek v poznámkách k vydání a také příspěvcích na blogu: novinky v desktopu a novinky v bezpečnosti. Vydány byly také oficiální deriváty Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Unity a Xubuntu. Jedná se o 10. LTS verzi.
Na YouTube je k dispozici videozáznam z včerejšího Czech Open Source Policy Forum 2024.
Fossil (Wikipedie) byl vydán ve verzi 2.24. Jedná se o distribuovaný systém správy verzí propojený se správou chyb, wiki stránek a blogů s integrovaným webovým rozhraním. Vše běží z jednoho jediného spustitelného souboru a uloženo je v SQLite databázi.
Byla vydána nová stabilní verze 6.7 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 124. Přehled novinek i s náhledy v příspěvku na blogu. Vypíchnout lze Spořič paměti (Memory Saver) automaticky hibernující karty, které nebyly nějakou dobu používány nebo vylepšené Odběry (Feed Reader).
OpenJS Foundation, oficiální projekt konsorcia Linux Foundation, oznámila vydání verze 22 otevřeného multiplatformního prostředí pro vývoj a běh síťových aplikací napsaných v JavaScriptu Node.js (Wikipedie). V říjnu se verze 22 stane novou aktivní LTS verzí. Podpora je plánována do dubna 2027.
Byla vydána verze 8.2 open source virtualizační platformy Proxmox VE (Proxmox Virtual Environment, Wikipedie) založené na Debianu. Přehled novinek v poznámkách k vydání a v informačním videu. Zdůrazněn je průvodce migrací hostů z VMware ESXi do Proxmoxu.
R (Wikipedie), programovací jazyk a prostředí určené pro statistickou analýzu dat a jejich grafické zobrazení, bylo vydáno ve verzi 4.4.0. Její kódové jméno je Puppy Cup.
Nedávno se tu objevil dotaz na hromadné stahování audia z webu mujrozhlas.cz. Já také občas poslouchám jejich pořady a měl jsem v plánu si takový skript někdy napsat. Níže je skript, který jsem vytvořil. Pod ním najdete více okomentovaný kód, s komentáři česky – ne každý umí Perl.
#! /usr/bin/env perl # mujrozhlas.pl – stahuje pořady z webu mujrozhlas.cz # Copyright (C) 2021 jiwopene (https://www.abclinuxu.cz/lide/jiwopene) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. use strict; use v5.13; use utf8; use Cwd; use File::Copy qw(move); use File::Fetch; use Getopt::Long; use HTML::TagParser; use HTTP::Tiny; use JSON::PP; my $download_unknown_urls = 0; my $overwrite_files = 0; my $skip_audio_download = 0; my $write_yaml = 0; my $make_subdirs = 0; my $output_root_dir = getcwd; # Děkuji za připomenutí tohoto řádku: # see https://www.abclinuxu.cz/poradna/linux/show/468500#26 binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; # Download something using HTTP(S) and return its response text. # # my $response_text = download($url); sub download { my ($url) = @_; my $resp = HTTP::Tiny->new->get($url); die "Nemůžu stáhnout $url: $resp->{status} $resp->{reason}\n" unless $resp->{success}; return $resp->{content}; } # Get episode metadata as hashmap. # # my %meta = get_episode_meta($episode_uuid); sub get_episode_meta { my ($episode_uuid) = @_; return decode_json download "https://api.mujrozhlas.cz/episodes/$episode_uuid"; } # Download episode to file with given name base. # # download_episode $name_base, $episode_meta; sub download_episode { my ($name_base, $episode_meta) = @_; my $audio_links = $episode_meta->{data}->{attributes}->{audioLinks}; for my $audio_link ( @$audio_links ) { my $audio_file_name = "$name_base.$audio_link->{bitrate}.$audio_link->{variant}"; $audio_file_name =~ tr@/@-@; unless ($skip_audio_download) { if (-e $audio_file_name) { if ($overwrite_files) { unlink $audio_file_name; } else { say "$audio_file_name již existuje, přeskakuji."; next; } } say "Stahuji $audio_file_name"; my $fetch = File::Fetch->new( uri => $audio_link->{url} ); unless ($fetch) { say "Přeskakuji $audio_link->{url}"; next; } my $where = $fetch->fetch(to => '/tmp'); unless ($where) { say "Nemůžu stáhnout $fetch->uri"; next; } move $where, "./$audio_file_name"; } else { say 'Stahování audia vypnuto, přeskakuji.'; } } } sub episode_info_from_elem { my ($episode_elem) = @_; my $episode_info_json = $episode_elem->getAttribute('data-entry'); my $episode_info = decode_json $episode_info_json; } # Download series with some url. # # URL example: # https://www.mujrozhlas.cz/stripky-z-archivu/stare-povesti-ceske # # download_series_by_url $page_url; sub download_series_by_url { my ($page_url) = @_; if (not $download_unknown_urls and $page_url !~ m@^https?://(www.)?mujrozhlas.cz/@) { say "URL stránky $page_url nevypadá platně, přeskakuji."; return 0; } my $page_html = download $page_url; my $page = HTML::TagParser->new($page_html); my @episode_elems; # Create and go into subdir if asked to do so. if ($make_subdirs) { my $detail_title_elem = $page->getElementById('detail-title'); my $episode_dir = $detail_title_elem->innerText; $episode_dir =~ tr@/@-@; mkdir $episode_dir unless -e $episode_dir; chdir $episode_dir; } # Get series ID. my $more_link_elem = $page->getElementsByClassName('more-link__link ajax'); if ($more_link_elem) { my $more_episodes_url = $more_link_elem->getAttribute('href'); # in format /ajax/ajax_list/FOO?page=1&size=9&id=FOO-1234&rid=1234 $more_episodes_url =~ m@ajax_list/(\w+)@; my $show_class = $1; $more_episodes_url =~ /[&?]id=(.*?)([&?]|$)/; my $show_id = $1; $more_episodes_url =~ /[&?]rid=(.*?)([&?]|$)/; my $show_rid = $1; my $episode_links_response = decode_json download "https://www.mujrozhlas.cz/ajax/ajax_list/$show_class?id=$show_id&rid=$show_rid&size=1000000"; # unset size= gives 20 entries my $episode_links_html = $episode_links_response->{snippets}->{$show_id}->{content}; my $episodes_page = HTML::TagParser->new($episode_links_html); @episode_elems = $episodes_page->getElementsByClassName("b-episode"); } else { # More link not available, fallback to direct HTML analysis. say 'Nemohu najít odkaz na více episod. Stahuji to co mám.'; @episode_elems = $page->getElementsByClassName("b-episode"); } for my $episode_elem ( @episode_elems ) { my $episode_info = episode_info_from_elem $episode_elem; say ''; say "#$episode_info->{id}: $episode_info->{title}"; my $episode_meta = get_episode_meta $episode_info->{uuid}; my $name_base = "$episode_info->{id}_$episode_info->{title}"; $name_base =~ tr@/@-@; if ($write_yaml) { YAML::PP->new->dump_file("$name_base.yaml", $episode_meta); } else { open my $meta_file, ">", "$name_base.json"; print $meta_file encode_json $episode_meta; close $meta_file; } download_episode $name_base, $episode_meta; } # Go back. chdir $output_root_dir; return 1; } sub print_help { $_ = "$0 -- strahování pořadů z mujrozhlas.cz Použití: perl $0 https://mujrozhlas.cz/lorem/ipsum Volby: --help Zobrazí tuto nápovědu. --unknown-urls Pokusí se stáhovat i z adres, které nevypadají platně. --overwrite Přepisuje soubory místo přeskočení existujících. --no-audio Bude stahovat jen metadata. --write-yaml Ukládá metadata jako YAML, ne JSON. --subdirs Vytvoří podadresář pro každý pořad. "; chomp; say; } my $show_help = 0; GetOptions( 'help' => \$show_help, 'unknown-urls' => \$download_unknown_urls, 'overwrite' => \$overwrite_files, 'no-audio' => \$skip_audio_download, 'write-yaml' => \$write_yaml, 'subdirs' => \$make_subdirs, ) or die 'Neplatné volby. Viz $0 --help.'; require YAML::PP if $write_yaml; if ($show_help) { print_help; exit; } say "mujrozhlas.pl, verze 1.1"; for my $url (@ARGV) { download_series_by_url $url; }
Použití je jednoduché: skriptu předáme jako argumenty jednu nebo více URL pořadů na webu
https://www.mujrozhlas.cz/
. Například takto:
perl mujrozhlas.pl https://www.mujrozhlas.cz/stripky-z-archivu/stare-povesti-ceske https://www.mujrozhlas.cz/bijacek
Skript používá také několik dlouhých voleb. --help
zobrazí nápovědu (vizte konec kódu, nechcete-li ho
spouštět). Ve výchozím nastavení ukládá metadata (JSON, případně YAML) do souboru s názvem ve tvaru
1234_Název episody.json
(resp. 1234_Název episody.yaml
) a zvuk do souboru s názvem ve tvaru
1234_Název episody.bitrate.typ
, kde 1234 je číselný identifikátor episody. Stahování audia vypneme volbou
--no-audio
. Volba --subdirs
vytváří pro pořady podadresáře.
Audio je stahované do dočasných souborů a poté překopírované do cílového adresáře. Pokud již soubor s audiem existuje,
přeskakuje se, ale soubor s metadaty se přepíše. Volba --overwrite
smaže případný soubor s audiem před
stažením.
Skript provádí základní ověření tvaru URL. Pokdu ho chcete obejít, zapněte --unknown-urls
, což toto ověření
vypne. To můžete použít například při stahování audia, ke kterému máte soubor HTML na nějakém zrcadle a nemáte původní
URL.
Skript je psaný v jazyce Perl. Ten je obzvlášť vhodný pro zpracovávání textů.¹ Obsahuje například podporu pro regulární výrazy včetně operátorů pro práci s nimi, atd. Vzhledem k tomu, že tazatel v diskusi napsal, že Perlu moc nerozumí, tak základy vysvětlím. Předpokládám alespoň základní znalosti programování.
Komentáře jsou od #
po konec řádku. Stringy píšeme do uvozovek (s expanzí proměnných), mezi apostrofy (bez
ní) nebo jiným způsobem (viz níže). Je dynamicky typovaný. Boolean neexistuje – prázdný string nebo 0 je false, jiné
hodnoty (s pár vyjímkami) jsou true.
Podmínky píšeme do if (podmínka) { tělo; }
(jako v C). Když napíšeme místo if
unless
, vyhodnocujue se negace podmínky (prohodí se větve if a else). Podmínku můžeme psát i za
statement, a to takto: télo if podmínka;
(případně s unless). Cyklus for-each se zapisuje takto: for
proměnná (pole) { tělo; }
.
Řádky s use
načítají balíčky (knihovny), případně určují verzi interpretru nebo jiná nastavení.
Názvy proměnných začínají sigilem: $
pro skaláry, @
pro pole a %
pro hashmapy.
Pokud čteme skalární prvek pole/hashmapy, píšeme $
. K metodám přistupujeme přes ->
,
k hodnotě z hashmapy pomocí ->{klíč}
(klíč je buď napsaný přímo, nebo jako string). K věcem v balíčku se
přistupuje pomocí ::
.
Lokální proměnné deklarujeme pomocí klíčového slova my
Subrutiny (funkce) vytváříme pomocí sub název { tělo }
. Argumenty dostane předané v poli @_
.
Regulární výrazy píšeme do /lomítek/, nahrazení s prefixem s
: s/co/čím/volby
. Jakmile píšeme
regulárný výrazy nebo stringy s tím prefixem (s, m, q, qw, qq, tr, …), můžeme zvolit i jiný znak než lomítka (závorky,
zavináče, …), takže nemusíme escapovat lomítka. Prefix s
uvozuje nahrazení, q
a qq
string (jako by byl s jednoduchými nebo dvojitými uvozovkami – dle počtu Qček), tr
nahrazení znaků (jako shellový příkaz tr(1)
), qw
pole stringů (slov), m
regulární
výraz.
Komentáře přidané do předchozího kódu jsou značené #-
.
#! /usr/bin/env perl # mujrozhlas.pl – stahuje pořady z webu mujrozhlas.cz # Copyright (C) 2021 jiwopene (https://www.abclinuxu.cz/lide/jiwopene) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. use strict; #- Více chyb. use v5.13; #- Verze Perlu. use utf8; #- Kód obsahue UTF-8. #- Knihovny. use Cwd; use File::Copy qw(move); use File::Fetch; use Getopt::Long; use HTML::TagParser; use HTTP::Tiny; use JSON::PP; #- Sem ukládáme volby z příkazové řádky. my $download_unknown_urls = 0; my $overwrite_files = 0; my $skip_audio_download = 0; my $write_yaml = 0; my $make_subdirs = 0; #- Uložíme si adresář při spuštění, abychom se sem mohli vrátit při stahování do podadresáře. my $output_root_dir = getcwd; #- stdout a stderr jsou v UTF-8. # Děkuji za připomenutí tohoto řádku: # see https://www.abclinuxu.cz/poradna/linux/show/468500#26 binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; # Download something using HTTP(S) and return its response text. # # my $response_text = download($url); sub download { #- Rozbijeme argumenty do proměnných. my ($url) = @_; my $resp = HTTP::Tiny->new->get($url); die "Nemůžu stáhnout $url: $resp->{status} $resp->{reason}\n" unless $resp->{success}; return $resp->{content}; } # Get episode metadata as hashmap. # # my %meta = get_episode_meta($episode_uuid); sub get_episode_meta { #- Rozbijeme argumenty do proměnných. my ($episode_uuid) = @_; return decode_json download "https://api.mujrozhlas.cz/episodes/$episode_uuid"; } # Download episode to file with given name base. # # download_episode $name_base, $episode_meta; sub download_episode { #- Rozbijeme argumenty do proměnných. my ($name_base, $episode_meta) = @_; my $audio_links = $episode_meta->{data}->{attributes}->{audioLinks}; for my $audio_link ( @$audio_links ) { #- Pro každou položku audioLink z metadat, #- Vygeneruj název souboru. my $audio_file_name = "$name_base.$audio_link->{bitrate}.$audio_link->{variant}"; #- Nahraď lomítka ASCII mínusy. $audio_file_name =~ tr@/@-@; #- Pokud nepřeskakujeme stahování audia, unless ($skip_audio_download) { # tak, pokud exisuje soubor s audieam if (-e $audio_file_name) { if ($overwrite_files) { #- a přepisujeme soubory unlink $audio_file_name; #- ho smažeme. } else { #- Jinak si postěžujeme a ... say "$audio_file_name již existuje, přeskakuji."; #- jdeme na další audioLink. next; } } say "Stahuji $audio_file_name"; #- Stáhneme URL do dočasného souboru $where (viz níže). my $fetch = File::Fetch->new( uri => $audio_link->{url} ); unless ($fetch) { #- Při chybě. say "Přeskakuji $audio_link->{url}"; next; } my $where = $fetch->fetch(to => '/tmp'); unless ($where) { #- Při chybě. say "Nemůžu stáhnout $fetch->uri"; next; } #- Přesuneme soubot na příslušné místo v pracovním adresáři. move $where, "./$audio_file_name"; } else { say 'Stahování audia vypnuto, přeskakuji.'; } } } sub episode_info_from_elem { my ($episode_elem) = @_; #- Vyčteme JSON se základními metadaty z HTML elementu. my $episode_info_json = $episode_elem->getAttribute('data-entry'); my $episode_info = decode_json $episode_info_json; } # Download series with some url. # # URL example: # https://www.mujrozhlas.cz/stripky-z-archivu/stare-povesti-ceske # # download_series_by_url $page_url; sub download_series_by_url { #- Rozbijeme argumenty do proměnných. my ($page_url) = @_; #- Ověření platnosti URL. if (not $download_unknown_urls and $page_url !~ m@^https?://(www.)?mujrozhlas.cz/@) { say "URL stránky $page_url nevypadá platně, přeskakuji."; return 0; } #- Stáhnu a naparsuji HTML stránky. my $page_html = download $page_url; my $page = HTML::TagParser->new($page_html); my @episode_elems; #- Sem přijdou elementy s metadaty. # Create and go into subdir if asked to do so. if ($make_subdirs) { #- Vyčteme titulek a nahradíme lomítka ASCII mínusy. my $detail_title_elem = $page->getElementById('detail-title'); my $episode_dir = $detail_title_elem->innerText; $episode_dir =~ tr@/@-@; #- Vytvoříme adresář pokud neexistuje (not -e). mkdir $episode_dir unless -e $episode_dir; #- Vstoupíme do něj. chdir $episode_dir; } # Get series ID. my $more_link_elem = $page->getElementsByClassName('more-link__link ajax'); if ($more_link_elem) { #- Pokud je na stránce odkaz na více episod, vezmeme jeho adresu, upravíme ji pro získání #- max. 1000000 záznamů a stáhneme HTML z ní (to je zabalené v JSONu), jinak ho bereme přímo #- ze stažené stránky. my $more_episodes_url = $more_link_elem->getAttribute('href'); # in format /ajax/ajax_list/FOO?page=1&size=9&id=FOO-1234&rid=1234 $more_episodes_url =~ m@ajax_list/(\w+)@; my $show_class = $1; #- $1 je první skupina z regexu. $more_episodes_url =~ /[&?]id=(.*?)([&?]|$)/; my $show_id = $1; #- $1 je první skupina z regexu. $more_episodes_url =~ /[&?]rid=(.*?)([&?]|$)/; my $show_rid = $1; #- $1 je první skupina z regexu. #- Vytvoříme si nové URL a stáhneme ho. my $episode_links_response = decode_json download "https://www.mujrozhlas.cz/ajax/ajax_list/$show_class?id=$show_id&rid=$show_rid&size=1000000"; # unset size= gives 20 entries #- Vyndáme z JSONu HTML, my $episode_links_html = $episode_links_response->{snippets}->{$show_id}->{content}; #- naparsujeme ho a ... my $episodes_page = HTML::TagParser->new($episode_links_html); #- vezmeme si z něj elementy se třídou b-episode. @episode_elems = $episodes_page->getElementsByClassName("b-episode"); } else { # More link not available, fallback to direct HTML analysis. say 'Nemohu najít odkaz na více episod. Stahuji to co mám.'; @episode_elems = $page->getElementsByClassName("b-episode"); } #- Pro každý element s odkazem an episodu, for my $episode_elem ( @episode_elems ) { my $episode_info = episode_info_from_elem $episode_elem; say ''; #- Odřádkuji. say "#$episode_info->{id}: $episode_info->{title}"; #- Napíšu ID a název episody. my $episode_meta = get_episode_meta $episode_info->{uuid}; #- Získám metadata episody. #- Vydělám si název souboru a ... my $name_base = "$episode_info->{id}_$episode_info->{title}"; #- nahradím lomítka ASCII mínusy. $name_base =~ tr@/@-@; #- Uložím metadata. if ($write_yaml) { YAML::PP->new->dump_file("$name_base.yaml", $episode_meta); } else { open my $meta_file, ">", "$name_base.json"; print $meta_file encode_json $episode_meta; close $meta_file; } #- Stáhnu episodu. download_episode $name_base, $episode_meta; } # Go back. chdir $output_root_dir; return 1; #- 1 je úspěch. } sub print_help { $_ = "$0 -- strahování pořadů z mujrozhlas.cz Použití: perl $0 https://mujrozhlas.cz/lorem/ipsum Volby: --help Zobrazí tuto nápovědu. --unknown-urls Pokusí se stáhovat i z adres, které nevypadají platně. --overwrite Přepisuje soubory místo přeskočení existujících. --no-audio Bude stahovat jen metadata. --write-yaml Ukládá metadata jako YAML, ne JSON. --subdirs Vytvoří podadresář pro každý pořad. "; chomp; #- Odstaním newline z konce. say; #- Vypíšu. } my $show_help = 0; GetOptions( 'help' => \$show_help, 'unknown-urls' => \$download_unknown_urls, 'overwrite' => \$overwrite_files, 'no-audio' => \$skip_audio_download, 'write-yaml' => \$write_yaml, 'subdirs' => \$make_subdirs, ) or die 'Neplatné volby. Viz $0 --help.'; require YAML::PP if $write_yaml; #- require jde dát do podmínky, use ne. if ($show_help) { print_help; exit; } say "mujrozhlas.pl, verze 1.1"; for my $url (@ARGV) { download_series_by_url $url; }
¹ To je můj názor. Zcela jistě si někteří myslí něco jiného.
Tiskni Sdílej:
supr skriptík užitečnej dík :D ;D
Ten je obzvlášť vhodný pro zpracovávání textů
na dělání regexpů je prej vo moc víc rychlejší než python třeba :O :O maďarskej krejčí to jakoby měřil hele :O ;D
810705_Osudy dobrého vojáka Švejka (11-13).128.mp3 810708_Osudy dobrého vojáka Švejka (4-13).256.mp3 810714_Osudy dobrého vojáka Švejka (3-13).256.mp3 810717_Osudy dobrého vojáka Švejka (1-13).128.mp3 810720_Osudy dobrého vojáka Švejka (10-13).128.mp3 810723_Osudy dobrého vojáka Švejka (6-13).128.mp3 810729_Osudy dobrého vojáka Švejka (5-13).256.mp3 810732_Osudy dobrého vojáka Švejka (9-13).128.mp3 810735_Osudy dobrého vojáka Švejka (8-13).128.mp3 810738_Osudy dobrého vojáka Švejka (2-13).128.mp3 810741_Osudy dobrého vojáka Švejka (13-13).128.mp3 810744_Osudy dobrého vojáka Švejka (7-13).128.mp3 810747_Osudy dobrého vojáka Švejka (12-13).128.mp3Logictejsi by bylo neco jako:
Osudy dobrého vojáka Švejka (01/13)[810717].mp3 Osudy dobrého vojáka Švejka (02/13)[810738].mp3Ale jinak diky moc za skriptik!
když sem to jako maďaroj dycky nazačátku zkompilovala hele vtom pythonu skriptík už nebyl pomalej 20x ale asi jakoby jenom 4-5x takže ztoho ten perl asi furt de jako víc lepšejší děladlo s textama :D ;D
ffmpeg -i "https://croaod.cz/stream/sem-dej-uuid.m4a/manifest.mpd" -map 0:0 -codec copy jmeno-souboru.m4a
Nemůžu stáhnout https://www.mujrozhlas.cz/radiokniha/marketa-hejkalova-dum-pod-namestim-vypraveni-jednoho-domu: 599 Internal ExceptionTrochu jsem googlil, našel jsem něco o firewallu na druhé straně. Kdyby někdo věděl, co s tím, budu rád. Jirka
mujrozhlas.pl, verze 1.1
URL stránky https://vltava.rozhlas.cz/joseph-heller-hlava-xxii-vyznamny-roman-kritizujici-nesmyslnost-valky-cernym-8976495 nevypadá platně, přeskakuji.
Poradíte?
TP
https:\/\/croaod.cz\/stream\/e619958d-d4db-4327-8b44-0ccf89cd762c.m4a\/manifest.mpd
wget -O - $URL | grep -o 'https:\\/\\/croaod.cz\\/stream\\/[^"]*\.mpd' rozhlas.html | sed 's/\\/\//g'| sed 's/\/\//\//g'
https://vltava.rozhlas.cz/joseph-heller-hlava-xxii-vyznamny-roman-kritizujici-nesmyslnost-valky-cernym-8976495
https://croaod.cz/stream/f35b9e13-faf6-46f4-8863-ac8a9ac09c3e.m4a/manifest.mpd
https://croaod.cz/stream/e619958d-d4db-4327-8b44-0ccf89cd762c.m4a/manifest.mpd
https://croaod.cz/stream/dab2edf1-d6f5-498e-9629-1cdeebe45144.m4a/manifest.mpd
https://croaod.cz/stream/045d955e-02be-4ab8-99ce-924b80801294.m4a/manifest.mpd
https://croaod.cz/stream/24b3866a-11f3-4d5c-b052-480c7ac04ded.m4a/manifest.mpd
https://croaod.cz/stream/2c2e40c7-89d4-4cc7-9d4b-c3929be8f7ea.m4a/manifest.mpd
https://croaod.cz/stream/94275875-6739-41eb-97d3-fcc3f231e349.m4a/manifest.mpd
https://croaod.cz/stream/b57ee671-42d8-4aa6-b6bb-3058f493a022.m4a/manifest.mpd
https://croaod.cz/stream/adec9233-4d4e-4a37-bce5-fb83b9309edc.m4a/manifest.mpd
https://croaod.cz/stream/61d9f93e-4b09-4537-91e1-c55c4c898c60.m4a/manifest.mpd
https://croaod.cz/stream/88b32d69-b480-46cc-888d-b918fe5455fe.m4a/manifest.mpd
https://croaod.cz/stream/0a3fb2cf-7316-4f7d-99ee-deccaa606d94.m4a/manifest.mpd
https://croaod.cz/stream/af73186e-a29c-4d23-a230-a291214f1230.m4a/manifest.mpd
https://croaod.cz/stream/ba975d10-6675-47ea-a8db-709bcd1ae5ce.m4a/manifest.mpd
https://croaod.cz/stream/ae8e728d-9b64-4282-9876-a69eb696149c.m4a/manifest.mpd
https://croaod.cz/stream/4ca55324-a703-42a1-bbcf-7d6882266c5e.m4a/manifest.mpd
https://croaod.cz/stream/ea756c97-d2c0-46c3-9e06-2e09607eca18.m4a/manifest.mpd
https://croaod.cz/stream/b80dc85e-02f9-4610-bf3e-107d6b1ea433.m4a/manifest.mpd
https://croaod.cz/stream/00bdcd56-7060-48f2-a908-8d882d758f67.m4a/manifest.mpd
https://croaod.cz/stream/3cf01aa1-9bc0-4522-a88b-7f9d9255c45f.m4a/manifest.mpd
https://croaod.cz/stream/21c7642d-a8fc-4741-9b84-bac4969fda05.m4a/manifest.mpd