| « Debugging Perl CGI scripts with Lighttpd | Missing directory structure in Mythweb videos » |
MythTV video streaming hack
One of our MythTV frontends is a small Dell netbook with SDD and therefor not much disk space. Therefor I decided to hack MythTV to stream videos from the Mythweb Video interface.
First off I had to enable MP4 streaming since I'm often transcoding to MP4.
--- modules/stream/stream_raw.pl.orig 2010-03-10 14:08:32.000000000 +0100
+++ modules/stream/stream_raw.pl 2010-03-10 14:08:48.000000000 +0100
@@ -39,4 +39,8 @@
$suffix = '.avi';
}
+ elsif ($basename =~ /\.mp4$/) {
+ $type = 'video/avi';
+ $suffix = '.mp4';
+ }
else {
print header(),
After enabling MP4 streaming you'll have to hack a bit in the tv.pl script. It starts out by determinig the recording type simply by looking at the request URL.
--- modules/stream/tv.pl.orig 2010-03-04 21:02:28.000000000 +0100
+++ modules/stream/tv.pl 2010-03-10 14:26:16.000000000 +0100
@@ -19,40 +19,69 @@
}
-# Which show are we streaming?
- our $chanid = url_param('chanid');
- our $starttime = url_param('starttime');
- if ($Path[1]) {
- $chanid = $Path[1];
- $starttime = $Path[2];
- $starttime =~ s/\.\w+$//;
- }
+# Determine wether we're streaming video or tv
-# Get the basename from the database
- my $sh = $dbh->prepare('SELECT basename, title, subtitle, endtime-starttime
- FROM recorded
- WHERE starttime=FROM_UNIXTIME(?)
- AND recorded.chanid = ?');
- $sh->execute($starttime, $chanid);
- our ($basename, $title, $subtitle, $runtime) = $sh->fetchrow_array();
- $sh->finish;
-
-# No match?
- unless ($basename =~ /\w/) {
- print header(),
- "Unknown recording requested.\n";
- exit;
- }
+if ($Path[2]) {
+ $type = "tv";
+} elsif ($Path[1]) {
+ $type = "video";
+}
-# Find the local file
- our $filename;
- $sh = $dbh->prepare('SELECT DISTINCT dirname
- FROM storagegroup');
- $sh->execute();
- while (my ($video_dir) = $sh->fetchrow_array()) {
- next unless (-e "$video_dir/$basename");
- $filename = "$video_dir/$basename";
- last;
- }
- $sh->finish;
+if ( $type eq "tv" ) {
+ # Which show are we streaming?
+ our $chanid = url_param('chanid');
+ our $starttime = url_param('starttime');
+ if ($Path[1]) {
+ $chanid = $Path[1];
+ $starttime = $Path[2];
+ $starttime =~ s/\.\w+$//;
+ }
+
+ # Get the basename from the database
+ my $sh = $dbh->prepare('SELECT basename, title, subtitle, endtime-starttime
+ FROM recorded
+ WHERE starttime=FROM_UNIXTIME(?)
+ AND recorded.chanid = ?');
+ $sh->execute($starttime, $chanid);
+ our ($basename, $title, $subtitle, $runtime) = $sh->fetchrow_array();
+ $sh->finish;
+
+ # Find the local file
+ our $filename;
+ $sh = $dbh->prepare('SELECT DISTINCT dirname
+ FROM storagegroup');
+ $sh->execute();
+ while (my ($video_dir) = $sh->fetchrow_array()) {
+ next unless (-e "$video_dir/$basename");
+ $filename = "$video_dir/$basename";
+ last;
+ }
+ $sh->finish;
+
+ 1;
+} elsif ( $type eq "video" ) {
+ # Which show are we streaming?
+ our $vidid = url_param('vidid');
+ if ($Path[1]) {
+ $vidid = $Path[1];
+ }
+ # Get the basename from the database
+ my $sh = $dbh->prepare('SELECT title, subtitle, filename
+ FROM videometadata
+ WHERE intid = ?');
+ $sh->execute($vidid);
+ our ($title, $subtitle, $basename) = $sh->fetchrow_array();
+ $sh->finish;
+
+ # Find the local file
+ our $filename;
+ $sh = $dbh->prepare('SELECT DISTINCT dirname
+ FROM storagegroup
+ WHERE groupname = "Videos"');
+ $sh->execute();
+ my $video_dir = $sh->fetchrow_array();
+ $filename = "$video_dir/$basename";
+
+ $sh->finish;
- 1;
+ 1;
+}
All that is now left is to make the webinterface display the new links.
--- modules/video/tmpl/default/video.php.orig 2010-03-10 13:30:31.000000000 +0100
+++ modules/video/tmpl/default/video.php 2010-03-10 13:57:53.000000000 +0100
@@ -307,5 +307,8 @@
<div id="<?php echo $video->intid; ?>_browse" class="hidden"><?php echo $video->browse; ?></div>
<div id="<?php echo $video->intid; ?>-title" class="title">
- <a href="<?php echo $video->url; ?>"><?php echo html_entities($video->title); ?></a><?php
+<?php echo html_entities($video->title); ?>
+ <a href="<?php echo $video->url; ?>"><img src="<?php echo skin_url ?>/img/video_sm.png"></a>
+ <a href="<?php echo ".//pl/stream/$video->intid" . ".asx"; ?>"><img src="<?php echo skin_url ?>/img/play_sm.png">
+ </a><?php
if (($video->season > 0) && ($video->episode >= 0))
printf('(S%02d E%02d)', $video->season, $video->episode);
As you can see this is just a quick hack and could probably have been better integrated into MythTV and my Perl skills feel a bit rusty too.
Sorry for the crappy display of code. If you want the diffs as properly formatted text files just drop me a line.
Let me know if you have any comments or other cool hacks.
Update: I split out my mythweb patches and you can download them here:
mythweb-0.22_p22763-carppout-debug.patch
mythweb-0.22_p22763-mp4-streaming.patch
mythweb-0.22_p22763-myth-video-streaming.patch
mythweb-0.22_p22763-path-list.patch
mythweb-0.22_p22763-tmpl-error.patch
Trackback address for this post
2 comments
I am very interested in this post as this seems the only mention (after a lot of searching) of being able to watch Video recordings made in MythVideo through MythWeb. I am trying to get this working for a complete video solution for the school I work for.
I know you mentioned this works for mp4 but does it work for avi? Unfortunately my coding skills in this area are zero so any help (and hand holding) would be fantastic!
Hope you can help
Regards
I just added MP4 support, it still supports the standard MPEG,Nuppel video and AVI formats. I just tested with a random AVI file and it works as expected.
I currently use the following diff file to patch mythweb mythweb-video-streaming.patch.