Jemand zu Hause?
plackup --listen :8000 testStreamingServer.pl --debug
print "Starting server\n";
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use LWP::UserAgent; use Plack::Runner; use File::Temp qw(tempfile); my $source_url = 'http://server1.example.com/stream.mp3'; my $redirect_url = 'http://server2.example.com/stream.mp3'; my $ua = LWP::UserAgent->new(); print "Starting server\n"; my $app = sub { print "Request received\n"; my $response = $ua->get($source_url); if ($response->is_success) { print "Source server is online, stream is playable\n"; my ($fh, $filename) = tempfile(); my $content_response = $ua->get($source_url, ':content_file' => $filename); my $headers = $content_response->headers(); print Dumper $headers; my $size = -s $filename; open(my $file, "<", $filename); my $file_content = do { local $/; <$file> }; close $file; return [ 200, [ 'Content-Type' => 'audio/mpeg', 'Content-Length' => $size, 'icy-metaint' => 8192, 'icy-name' => 'My Stream', 'icy-description' => 'My stream description', 'icy-genre' => 'variety', 'icy-pub' => 1, 'icy-br' => 128, 'Connection' => 'close' ], [ $file_content ], ]; } else { print "Source server is offline, redirecting to backup stream\n"; return [ 302, [ 'Location' => $redirect_url, 'Connection' => 'close' ], [], ]; } }; my $runner = Plack::Runner->new; $runner->parse_options(qw(--listen :8000 --server HTTP::Server::PSGI)); $runner->run($app); print "Server started\n";
LWP::UserAgent so ändern, dass er die Quellen portionsweise liest und zweitens Deinen Plack-Server so ändern, dass er einen Header Accept-Ranges: bytes ausspuckt und dann auch nur die Teile ausliefert, die Dein Browser verlangt. Und dann holst Du mit dem $ua die Portionen erst dann, wenn der Browser sie von Dir verlangt. Du brauchst dann gar nichts zu speichern!
my $response = $ua->get($source_url);
QuoteBeim Streaming holt man die Datei portionsweise und liefert diese Portionen dann gleich wieder aus, ohne die jemals lokal speichern zu müssen.
2023-01-17T14:41:29 cbxk1xg[...] Bei einem icecast HTTP-Stream wird die Verbindung jedoch über die gesamte Zeit aufrecht erhalten und die Nutzdaten werden solange gesendet bis ein anderes Ereignis eintritt. Erst am Ende der Übertragung, durch stoppen des Streams im Browser oder durch das kicken das Clients am Server, wird der HTTP Status Code gesendet. Bricht die Verbndung ab wird gar kein Status Code gesendet.
HTTP-Streaming? Dazu gibt es Standard-Entwürfe (im Wikipedia-Artikel verlinkt). Da zerlegt der Server die Medien in "Segmente" und der Client setzt die zusammen, es laufen also mehrere HTTP-Requests, um eine MP3-Datei zu übertragen. Der Content-type bei solchen Protokollen ist nicht audio/mpeg!
LWP::UserAgent ein get ausführst, dann blockiert das so lange, bis der komplette Inhalt der URL übertragen wurde. Und wenn der Server kontinuierlich sendet, dann... passiert das nie, und Dein Code hängt an der Stelle. Wie Du ja gemerkt hast.
Mojo::UserAgent mit seiner Methode get_p) und für den Server, um "portionsweise" Daten austauschen zu können.Quoteund dann an beliebig viele User verteilt.
Quoteicy-metaint is the number of bytes of media stream data between each metadata chunk.
Suppose I have an internet radio station, with icy-metaint value of 8192. The data from the server will look something like this:
[8192 bytes audio] [metadata] [8192 bytes audio] [metadata] …
1
2
3
4
5
6
7
8
root@test-server:~# curl -v http://localhost:8000
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.74.0
> Accept: */*
>
1
2
3
4
root@test-server:~# plackup --listen :8000 streamingServer.pl --debug
Starting server
HTTP::Server::PSGI: Accepting connections at http://0:8000/
Request received
2023-01-18T19:52:15 cbxk1xgKeine Ahnung welcher Stream das sein soll?! Sollte das ein Guerilla SEO move von dir sein? :-)
QuoteHTTP Audio-Streaming wird im Vergleich zu Video-Streaming sehr stiefmütterlich behandelt.
1 2 3 4 5 6 7 8 9
use strict; use warnings; use IO::Socket; my $s = IO::Socket::INET->new("46.105.122.141:9676") or die $!; $s->print("GET / HTTP/1.0\r\n\r\n"); # NonStopOldies Stream auf Konsole print while <$s>;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HTTP/1.0 200 OK
icy-notice1:<BR>This stream requires <a href="http://www.winamp.com">Winamp</a><BR>
icy-notice2:Shoutcast DNAS/posix(linux x86) v2.6.1.777<BR>
Accept-Ranges:none
Access-Control-Allow-Origin:*
Cache-Control:no-cache,no-store,must-revalidate,max-age=0
Connection:close
icy-name:NonStopOldies
icy-genre:Oldies
icy-br:128
icy-sr:44100
icy-url:http://www.nonstopoldies.com
icy-pub:1
content-type:audio/mpeg
X-Clacks-Overhead:GNU Terry Pratchett
use strict; use warnings;