Difference between revisions of "User:Dswimboy"

From MythTV Official Wiki
Jump to: navigation, search
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
MythTV is awesome for my roommates and I. We love the commercial skip!
+
My current rig came from newegg for about $600
 +
* Zotac Mini-ITX motherboard with NVIDIA GeForce 9000 and HDMI out (GF9300-K-E)
 +
* Intel Pentium dual-core 3.2 GHz CPU (E6700 Wolfdale)
 +
* 4 GB (2 x 2GB) RAM
 +
* 2 TB Hitachi Deskstar hard drive (HDS722020ALA330)
 +
* Micro ATX case, power supply, fan
 +
* Hauppauge dual TV tuner (WinTV-HVR-2250)
  
== My Setup ==
+
The system is running ubuntu.
  
Combined FE/BE.
+
I schedule all of my programs through [[mythweb]].
=== Hardware ===
 
* VIA EPIA 5000
 
* 512MB Ram
 
* 160GB Western Digital 7200rpm HDD
 
* Hauppauge WinTV-PVR-350
 
  
=== Software ===
+
I haven't gotten the remote on the 2250 working. I was using a corded keyboard for a while, which was a pain. I've since enabled the [[Frontend control socket]] and I'm using the [http://code.google.com/p/mythmote/ mythmote] app on my Android phone as a remote.
* Debian Sid
 
* Kernel v2.6.18-3-486
 
* xorg v1:7.1.0
 
* ivtv drivers v0.8.2, firmware v1.18.21.22168
 
* lirc version v0.8.0
 
* [http://www.icewm.org/ IceWM] window manager
 
* MythTV v0.20.20060828-3
 
 
 
== What's working for me ==
 
* XV on PVR-350
 
* Live TV/TV recording
 
* TV Listings from [http://labs.zap2it.com/ Zap2it]
 
* [[MythMusic]]
 
* [[MythGallery]]
 
* [[MythWeb]]
 
* [[Windows Watching Recordings in Windows with MythTv Player]]
 
* Using irexec to restart Myth when something goes wrong
 
* myth2ipod with modifications
 
 
 
== What's not ==
 
* On Screen Program Guide: stopped working at some point. not sure why.
 
 
 
== Comments ==
 
Switching to IceWM was a big help on cutting down login time.
 
 
 
== Useful config info ==
 
=== Xorg ===
 
 
 
Important xorg.conf excerpts for PVR-350 and TV-Out
 
 
 
Device BusID is in ''hexadecimal''.
 
<pre>
 
Section "Device"
 
Identifier "Hauppauge PVR 350 iTVC15 Framebuffer"
 
Driver "ivtvdev"
 
Option  "ivtv" "/dev/fb0"
 
Option  "fbdev" "/dev/fb0"
 
BusID  "PCI:0:20:0"
 
Screen 0
 
EndSection
 
 
 
Section "Screen"
 
        Identifier "TV"
 
        Device "Hauppauge PVR 350 iTVC15 Framebuffer"
 
        Monitor "NTSC Monitor"
 
        DefaultDepth 24
 
        DefaultFbbpp 32
 
        Subsection "Display"
 
                Depth 24
 
                FbBpp 32
 
                Modes "720x480"
 
        EndSubsection
 
EndSection
 
 
 
Section "Monitor"
 
        Identifier "NTSC Monitor"
 
        HorizSync 30-68
 
        VertRefresh 50-120
 
        DisplaySize 183 122
 
        Mode "720x480"
 
                # D: 34.563 MHz, H: 37.244 kHz, V: 73.897 Hz
 
                DotClock 34.564
 
                HTimings 720 752 840 928
 
                VTimings 480 484 488 504
 
                Flags  "-HSync" "-VSync"
 
        EndMode
 
EndSection
 
</pre>
 
 
 
=== (Re)-Start Myth Frontend ===
 
startmythfrontend script to restart MythTV via irexec.
 
<pre>
 
#!/bin/bash
 
 
 
# (Re-)starts mythfrontend
 
# This script gets executed when the "Go" button on the remote is pressed
 
#
 
# Torsten Schenkel, edited by Matt Burke
 
 
 
# Reset the alpha values for ivtv-fb so we can see the X desktop (not always done automatically)
 
ivtvfbctl /dev/fb0 --globalalpha off --localalpha off
 
 
 
# Kill and start mythfrontend
 
killall mythfrontend
 
 
 
# Restart mythfrontend
 
echo "`date` RESTART" >> /home/burkemw/mythfrontend.log
 
export DISPLAY=:0.0
 
mythfrontend >> /home/burkemw/mythfrontend.log &
 
 
 
</pre>
 
 
 
=== LIRC ===
 
 
 
the .lircrc file (buttons as per the DVICO remote, which I think are now standard in the lirc distribution)
 
<pre>
 
## irexec
 
begin
 
prog = irexec
 
button = GO
 
config = sudo -u mythtv /home/burkemw/bin/startmythfrontend &
 
end
 
</pre>
 
 
 
=== myth2ipod ===
 
 
 
myth2ipod script. modified from [http://www.myth2ipod.com/myth2ipod.html myth2ipod]. I use ffmpeg directly, instead of nuvexport to transcode files. i haven't enabled removing commercials. it takes a while. i've added functionality for ffmpeg to update progress in mythconverge table. (ffmpeg takes the longest by far)
 
<pre>
 
#!/usr/bin/perl -w
 
# VERSION: 1.0b2 - myth2ipod
 
# Get the latest version, and change log at myth2ipod.com
 
# Author: Chris aka Wififun - email: wififun@myth2ipod.com
 
# Contributions and testing by Paul Egli
 
# modified to use nuvexport by starv at juniks dot org
 
 
 
# Includes
 
use DBI;
 
use Getopt::Long;
 
use File::Path;
 
use Expect;
 
 
# User variables
 
my $portable = "ipod";
 
my $feedfile = "/var/lib/mythipod/feed.php";
 
my $feedpath = "/var/lib/mythipod/";
 
my $wwwloc = "/var/www/";
 
my $feedurl = "http://192.168.1.10/mythipod/";
 
my $nuvoptions ="--mode=iPod --nice=19 --cutlist --nodenoise --nodeinterlace --nomultipass";
 
 
# Some variables
 
our ($dest, $format, $usage);
 
our ($db_host, $db_user, $db_name, $db_pass, $video_dir);
 
our ($hostname, $db_handle, $sql, $statement, $row_ref);
 
    our ($chanid, $start, $nuvfile, @nuvarray);
 
my $rebuild = '0';
 
my $encode = '0';
 
my $debug = '0';
 
my $setup = '0';
 
my $cut = '0';
 
my( $rightnow ) = `date`;
 
 
 
GetOptions ("rebuild" => \$rebuild,
 
"encode"  => \$encode,
 
"debug" => \$debug,
 
"setup" => \$setup,
 
"cut" => \$cut);
 
 
 
if ($setup == 1){
 
system("clear");
 
print "Setup will do everything needed to run this script.\n";
 
print "This has only been tested on KnoppMyth R5A22.\n";
 
print "make sure you have edited the variables for your conguration.\n";
 
my $cksetup = &promptUser("\nAre you sure you want to procceed?","n");
 
if ($cksetup =~ "y") {
 
DoSetup();
 
exit;
 
}
 
print "Setup exited. Nothing done.\n";
 
exit;
 
}
 
elsif ($rebuild == 1){
 
GenerateRSSFeed();
 
print "Rebuilding of RSS feed is complete.\n";
 
exit;
 
}
 
else {
 
Encode4Portable();
 
print "$title is ready for your $portable\n";
 
 
# Check to see if the feed file exists; if not, create it.
 
if (! -e $feedfile) {
 
print "No feed file found. I will make one for you.\n";
 
GenerateRSSFeed();
 
print "All done.\n";
 
}
 
}
 
 
 
sub Encode4Portable{
 
if ($#ARGV != 1) {
 
print "Encoding requires options.\nusage: myth2ipod <options> DIRECTORY FILE\n";
 
exit;
 
}
 
 
# Get the show information
 
$directory = $ARGV[0];
 
$file = $ARGV[1];
 
@file = split(/_/, $file);
 
$chanid = $file[0];
 
$start = substr $file[1],0,14;
 
if($debug == 1){ print "$chanid\n$start\n"};
 
if (! -e $directory."/".$file){
 
print "Opps, the file ".$directory.$file." does not exist.\n";
 
exit;
 
}
 
 
# Connect to the database
 
PrepSQLRead();
 
$db_handle = DBI->connect("dbi:mysql:database=$db_name:host=$db_host", $db_user, $db_pass)
 
or die "Cannot connect to database: $!\n\n";
 
$sql = "SELECT title, subtitle, description, category, starttime FROM recorded WHERE chanid = $chanid AND DATE_FORMAT(starttime,'%Y%m%d%H%i%s') = $start";
 
 
 
$statement = $db_handle->prepare($sql)
 
or die "Couldn't prepare query '$sql': $DBI::errstr\n";
 
 
$statement->execute()
 
or die "Couldn't execute query '$sql': $DBI::errstr\n";
 
$row_ref = $statement->fetchrow_hashref();
 
if($debug == 1){ print "$row_ref->{starttime}\n"};
 
$title = $row_ref->{title};
 
$subtitle = $row_ref->{subtitle};
 
$recorddate = $row_ref->{starttime};
 
$description = $row_ref->{description};
 
$category = $row_ref->{category};
 
$filename = $title."-".$subtitle."-".substr $start, 0, 8;
 
$filename =~ s/ /_/g;
 
$filename =~ s/&/+/g;
 
$filename =~ s/\047//g;
 
    $filename =~ s/[^+0-9a-zA-Z_-]+/_/g;
 
    $filename =~ s/_$//g;
 
 
printf("Starting nuvexport...\n");
 
EncodeIt();
 
printf("Nuvexport completed, starting xml generation...\n");
 
CreateItemXML();
 
printf("XML file created for \"$filename\" : Yipeee\n");
 
printf("Cleaning up temporary files\n");
 
$cmd = "rm -f $feedpath$chanid\_$start.temp.mp4";
 
print $cmd."\n";
 
if(system($cmd)) { print "Removing nuvexport temp file failed\n"; }
 
 
# remove the cutlist incase we added it.
 
if ($cut == 1){
 
printf("Generating cutlist\n");
 
$cmd = "/usr/bin/mythcommflag --chanid $chanid --starttime $start --clearcutlist";
 
print $cmd."\n";
 
if(system($cmd)) { print "It looks like I was not able to generate a cutlist.\n"; }
 
}
 
return 0;
 
}
 
 
 
#
 
# Encode for Portable
 
#
 
sub EncodeIt {
 
# Create cutlist from commercial flagging if -cut was passed to the script
 
if ($cut == 1) {
 
printf("Generating cutlist\n");
 
$cmd = "/usr/bin/mythcommflag --chanid $chanid --starttime $start --gencutlist";
 
print $cmd."\n";
 
if(system($cmd)) { print "It looks like I was not able to generate a cutlist.\n"; }
 
}
 
 
# Use nuvexport to do the work
 
# $cmd = "/usr/bin/nuvexport --chanid=$chanid --start=$start $nuvoptions --filename=$chanid\_$start.temp --path=$feedpath";
 
$cmd = "ffmpeg -vcodec xvid -b 300 -qmin 3 -qmax 5 -bufsize 4096 -g 300 -acodec aac -ab 96 -i /$directory/$file -s 320x240 -aspect 4:3 $feedpath$chanid\_$start.temp.mp4";
 
print $cmd."\n";
 
ffmpegExpect();
 
 
$command->soft_close();
 
 
# Now clean up the output so iPods with firmware 1.1 and above can use it
 
$cmd = "/usr/bin/MP4Box -add $feedpath$chanid\_$start.temp.mp4 $feedpath$chanid\_$start.$portable.mp4";
 
print $cmd."\n";
 
if(system($cmd)) { print "MP4Box cleanup seems to have failed\n"; }
 
return 0;
 
}
 
 
 
#
 
# Use Expect to update database on transcoding progress
 
#
 
sub ffmpegExpect {
 
$command = Expect->spawn($cmd);
 
$update = 1;
 
($hrs, $min, $sec, $msec, $seconds,$frames) = (0,0,0,0,0,1);
 
 
if ($command->expect(2, '-re', "Duration: [0-9]{2,2}:[0-9]{2,2}:[0-9]{2,2}.[0-9],")) {
 
$command->exp_match() =~ /([0-9]{2,2}):([0-9]{2,2}):([0-9]{2,2}).([0-9])/;
 
($hrs, $min, $sec, $msec) = ($1, $2, $3, $4);
 
$seconds = $msec/10 + $sec + 60 * ( $min + 60 * ($hrs) );
 
} else { $update = 0; }
 
 
if ($command->expect(2, '-re', ", [0-9]{2,2}.[0-9]{2,2} fps")) {
 
$command->exp_match() =~ /, ([0-9\.]{5,5}) /;
 
$frames = $seconds * $1;
 
} else { $update = 0; }
 
 
# `jobqueue`.`chanid`='%s' AND `jobqueue`.`starttime`='%s'
 
if ($update) {
 
while ($command->expect(undef, '-re', "frame= *[0-9]+ q")) {
 
$command->exp_match() =~ /frame= *([0-9]+) q/;
 
$completion = ($1) / ($frames) * 100;
 
$sql = sprintf("UPDATE `jobqueue` SET `comment`='%.3f%% Completed (ffMPEG Transcoding)', `statustime`=NOW() WHERE `jobqueue`.`chanid`='%s' AND `jobqueue`.`starttime`='%s' LIMIT 1 ;",$completion,$chanid,$start);
 
$statement = $db_handle->prepare($sql) or die "Couldn't prepare query '$sql': $DBI::errstr\n";
 
$statement->execute() or die "Couldn't execute query '$sql': $DBI::errstr\n";
 
}
 
}
 
}
 
 
 
#
 
# Create XML with <ITEM> tag for this video file
 
#
 
sub CreateItemXML {
 
open(ITEM, ">$feedpath$chanid\_$start.$portable.xml");
 
print ITEM "<item>\n"; 
 
print ITEM "<title>".&encodeForXML($title." - ".$subtitle)."</title>\n";
 
print ITEM "<itunes:author>MythTV</itunes:author>\n"; 
 
print ITEM "<author>MythTV</author>\n"; 
 
print ITEM "<itunes:category text=\"TV Shows\"></itunes:category>\n";
 
print ITEM "<comments>".&encodeForXML($file)."</comments>\n"; 
 
print ITEM "<description>".&encodeForXML($description)."</description>\n"; 
 
print ITEM "<pubDate>".$recorddate."</pubDate>\n"; 
 
print ITEM "<enclosure url=\"".&encodeForXML("$feedurl$chanid\_$start.$portable.mp4")."\" type=\"video/quicktime\" />\n"; 
 
print ITEM "<itunes:duration></itunes:duration>\n"; 
 
print ITEM "<itunes:keywords>".&encodeForXML($title." - ".$subtitle." - ".$category)."</itunes:keywords>\n";
 
print ITEM "<category>".&encodeForXML($category)."</category>\n";
 
print ITEM "</item>\n";
 
print "\"$filename\" has been added to the feed.\n";
 
close(ITEM);
 
return 0;
 
}
 
 
 
#
 
# Generate the RSS feed by combining the ITEM XML Files
 
#
 
sub GenerateRSSFeed {
 
 
 
open(RSS, ">$feedfile");
 
print RSS "<?php\n";
 
print RSS "header(\"Content-Type: text/xml\");\n";
 
print RSS "echo \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"; ?>\n";
 
print RSS "<rss xmlns:itunes=\"http://www.itunes.com/DTDs/Podcast-1.0.dtd\" version=\"2.0\">\n";
 
print RSS "<channel>\n";
 
print RSS "<title>MythTV - <? if (\$_GET['title'] == \"\") { \$title = \"*\"; echo \"Recorded Programs\"; }\n";
 
print RSS "else { \$title = \$_GET['title']; echo str_replace(\"_\",\" \",\$_GET['title']); } ?> </title>\n";
 
print RSS "<itunes:author>MythTV - myth2ipod</itunes:author>\n";
 
print RSS "<link>".&encodeForXML($feedurl)."</link>\n";
 
print RSS "<itunes:subtitle>Transcoded recording for your iPod Video.</itunes:subtitle>\n";
 
print RSS "<itunes:summary>Myth TV Recorded Programs for the iPod v.1</itunes:summary>\n";
 
print RSS "<description>Myth TV Recorded Programs for the iPod v.1</description>\n";
 
print RSS "<itunes:owner>\n";
 
print RSS "<itunes:name>MythTV</itunes:name>\n";
 
print RSS "<itunes:email>mythtv\@localhost</itunes:email>\n";
 
print RSS "</itunes:owner>\n";
 
print RSS "<itunes:explicit>No</itunes:explicit>\n";
 
print RSS "<language>en-us</language>\n";
 
print RSS "<copyright>Copyright 2005.</copyright>\n";
 
print RSS "<webMaster>mythtv\@localhost</webMaster>\n";
 
print RSS "<itunes:image href=\"http://myth2ipod.com/mythipod_200.jpg\" />\n";
 
print RSS "<itunes:category text=\"TV Shows\"></itunes:category>\n";
 
print RSS "<category>TV Shows</category>\n";
 
print RSS "<itunes:image href=\"http://myth2ipod.com/mythipod_200.jpg\"/>";
 
print RSS "<image>";
 
print RSS "<url>http://myth2ipod.com/mythipod_200.jpg</url>\n";
 
print RSS "<title>MythTV 2 iPod</title>\n";
 
print RSS "<link>".&encodeForXML($feedurl)."</link>\n";
 
print RSS "<width>200</width>\n";
 
print RSS "<height>200</height>\n";
 
print RSS "</image>\n";
 
print RSS "<? foreach (glob(\$title\.\"*\.$portable\.xml\") as \$file) {include \$file;} ?>\n";
 
print RSS "</channel>\n";
 
print RSS "</rss>\n";
 
close(RSS);
 
if($debug == 1){ print "I created a feed file, was I supposed to?\n"};
 
 
 
return 0;
 
}
 
 
 
# substitute for XML entities
 
sub encodeForXML {
 
local $result;
 
$result = $_[0];
 
$result =~ s/&/&amp;/g;
 
$result =~ s/</&lt;/g;
 
$result =~ s/>/&gt;/g;
 
$result;
 
}
 
 
 
 
 
#
 
# This code taken from one of the mythlink.sh scripts to get MySQL information
 
#
 
sub PrepSQLRead{
 
# Get the hostname of this machine
 
    $hostname = `hostname`;
 
    chomp($hostname);
 
   
 
# Read the mysql.txt file in use by MythTV.
 
# could be in a couple places, so try the usual suspects
 
    my $found = 0;
 
    my @mysql = ('/usr/local/share/mythtv/mysql.txt',
 
                '/usr/share/mythtv/mysql.txt',
 
                '/etc/mythtv/mysql.txt',
 
                '/usr/local/etc/mythtv/mysql.txt',
 
                "$ENV{HOME}/.mythtv/mysql.txt",
 
                'mysql.txt'
 
                );
 
    foreach my $file (@mysql) {
 
        next unless (-e $file);
 
        $found = 1;
 
        open(CONF, $file) or die "Unable to open $file:  $!\n\n";
 
        while (my $line = <CONF>) {
 
        # Cleanup
 
            next if ($line =~ /^\s*#/);
 
            $line =~ s/^str //;
 
            chomp($line);
 
        # Split off the var=val pairs
 
            my ($var, $val) = split(/\=/, $line, 2);
 
            next unless ($var && $var =~ /\w/);
 
            if ($var eq 'DBHostName') {
 
                $db_host = $val;
 
            }
 
            elsif ($var eq 'DBUserName') {
 
                $db_user = $val;
 
            }
 
            elsif ($var eq 'DBName') {
 
                $db_name = $val;
 
            }
 
            elsif ($var eq 'DBPassword') {
 
                $db_pass = $val;
 
            }
 
        # Hostname override
 
            elsif ($var eq 'LocalHostName') {
 
                $hostname = $val;
 
            }
 
        }
 
        close CONF;
 
    }
 
    die "Unable to locate mysql.txt:  $!\n\n" unless ($found && $db_host);
 
    return 0;
 
}
 
 
 
sub promptUser {
 
  local($promptString,$defaultValue) = @_;
 
  if ($defaultValue) {
 
      print $promptString, "[", $defaultValue, "]: ";
 
  } else {
 
      print $promptString, ": ";
 
  }
 
 
 
  $| = 1;              # force a flush after our print
 
  $_ = <STDIN>;        # get the input from STDIN (presumably the keyboard)
 
  chomp;
 
  if ("$defaultValue") {
 
      return $_ ? $_ : $defaultValue;    # return $_ if it has a value
 
  } else {
 
      return $_;
 
  }
 
}
 
 
 
sub DoSetup {
 
print "\nNot ready yet. How do you send the cd command from perl?\n";
 
return 0;
 
}
 
</pre>
 

Latest revision as of 20:57, 4 December 2011

My current rig came from newegg for about $600

  • Zotac Mini-ITX motherboard with NVIDIA GeForce 9000 and HDMI out (GF9300-K-E)
  • Intel Pentium dual-core 3.2 GHz CPU (E6700 Wolfdale)
  • 4 GB (2 x 2GB) RAM
  • 2 TB Hitachi Deskstar hard drive (HDS722020ALA330)
  • Micro ATX case, power supply, fan
  • Hauppauge dual TV tuner (WinTV-HVR-2250)

The system is running ubuntu.

I schedule all of my programs through mythweb.

I haven't gotten the remote on the 2250 working. I was using a corded keyboard for a while, which was a pain. I've since enabled the Frontend control socket and I'm using the mythmote app on my Android phone as a remote.