Video and Audio with Perl and DLNA

Max Maischein

Frankfurt.pm

Overview

  • What is DLNA?

  • Live Demos (with code)

  • Future Developments

Who am I

  • Max Maischein

  • DZ BANK Frankfurt

  • Deutsche Zentralgenossenschaftsbank

  • Informationsmanagement

Disclaimer

  • Using Chromecast

  • Closed API

  • Slow device

  • Huge lag (5 s)

  • I lost interest

Disclaimer

Sorry

Disclaimer

Sorry

Upside: Implementing your own Chromecast is trivial (bonus section)

What is DLNA?

Digital Living Network Alliance

Network your home media appliances

What is DLNA?

What is DLNA?

What is DLNA?

What is DLNA?

What is DLNA?

What is DLNA?

What is DLNA?

Existing DLNA players/renderers

  • Your "Smart" TV (renderer+remote control)

  • PS3 (not PS4, only renderer)

  • Fritz!Box (server)

  • Squeezebox (now Logitech), Twonky Media Server

  • XBMC / Kodi (Server+Renderer, OpenELEC, Android, Raspberry Pi)

How does DLNA work?

  • Discovery (UPnP)

  • Transport (HTTP)

Discovery with Perl / UPnP

Discovery with Perl / UPnP

Discovery with Perl / UPnP

Live demo 1 - discovery

 1:  $timeout ||= 3;
 2: 
 3:  for my $device (
 4:    DLNA::Device::find_media_renderers( mx => $mx )
 5:  ) {
 6:    print join "\t",
 7:        $device->getfriendlyname,
 8:        $device->getmanufacturer;
 9:    print "\n";
10:  };

Transport with Perl / HTTP

Transport with Perl / HTTP

Transport with Perl / HTTP

Transport with Perl / HTTP

Goal

Send Youtube HD video via DLNA to TV

Goal

Extract HTTP URL

Goal

Send video URL to TV

Goal

Watch

Problems of DLNA

  • Samsung does not access outside HTTP URLs

  • Samsung really wants MediaInfo.sec HTTP header

  • Content-Type: video/mp4v instead of video/mpeg4

  • "Custom" HTTP clients

  • All Media Servers have special per-device hacks

Reality

Reality

Proxy

  • Initialize with (remote) URL (or local file)

  • Get back local HTTP URL

  • Give local URL to DLNA device

  • Device requests local URL

  • Proxy requests remote URL

  • Proxy rewrites response headers (video/mp4v)

  • Watch content

What have I written?

  • Device discovery

  • Remote control

  • Rewriting HTTP "proxy" for Samsung

Live demo 2 - Local HTTP music server

 1:  use AnyEvent::DLNAServer::MediaServer;
 2:  use DLNA::Device;
 3:  use JWZ::YouTubeDown;
 4:
 5:  my $media= AnyEvent::DLNAServer::MediaServer->new();
 6:  $info= $media->add_file($resource, expires => 180);
 7:  my $url= $info->{dlna_url};
 8:
 9:  ...

Live demo 2 - Local HTTP music server

 1:  use AnyEvent::DLNAServer::MediaServer;
 2:  use DLNA::Device;
 3:  use JWZ::YouTubeDown;
 4:
 5:  my $media= AnyEvent::DLNAServer::MediaServer->new();
 6:  $info= $media->add_file($resource, expires => 180);
 7:  my $url= $info->{dlna_url};
 8:
 9:  my $device= DLNA::Device::find_device( $device_name )
10:      or die "No UPnP device found for '$device_name'";
11:
12:  print sprintf "Playback of %s using %s\\n", $url,
13:      $device->getfriendlyname;
14:  ...

Live demo 2 - Local media server

 1:  ...
 2:  # Now, start the playback
 3:  my $renderer = Net::UPnP::AV::MediaRenderer->new();
 4:  $renderer->setdevice($device);
 5:  $renderer->stop();
 6:  ...

Live demo 2 - Local media server

 1:  ...
 2:  # Now, start the playback
 3:  my $renderer = Net::UPnP::AV::MediaRenderer->new();
 4:  $renderer->setdevice($device);
 5:  $renderer->stop();
 6:
 7:  $renderer->setAVTransportURI(CurrentURI => $url);
 8:  $renderer->play(); 
 9:
10:  print "Server idle, waiting for things to happen\n";
11:  AnyEvent->condvar->recv;

Live demo 3 - Internet

(Reproxied) YAPC::Europe stream

What needs to be written

  • Media metadata (title, cover, length, ...)

  • Proper M3U playlist handling

  • AnyEvent DLNA server

  • pDLNA http://www.pdlna.org

  • Resource crawler / indexer

  • Media proxy to aggregate/restructure existing media

Ideas

  • Display a GoPro stream on TV

  • Serve a VNC session as mpg stream

Thanks

Thanks

Questions?

Thanks

corion@corion.net

All slides are online at

http://corion.net/talks/

Net::UPnP

Net::UPnP::HTTP::AnyEvent, soon on CPAN

https://github.com/corion/app-dlna-youtube on Github

Bonus - our own Chromecast

  • Chrome as DLNA Media Renderer

  • Thin Javascript slave

  • Perl listens to UPnP

  • Perl tells Chrome to fetch HTTP data

  • Profit

Dancer App

  • Send HTML+Javascript to slave

  • Push updates with Server Sent Events

  • Send "Pause" event

  • No fast forward

  • No time synchronisation

Rage Driven Development

  • jwz writes youtubedownload.pl

  • Youtube does not like people accessing the video directly

  • You can feel the anger emanating from the script

  • Monkeypatch to load that script as a module

  • not on CPAN, see JWZ::YouTubeDown on github

  • Also see youtube-dl / Youtube::DL

More Links

Link to Web Remote/Player

https://github.com/corion/app-dlna-youtube