Just made another quick update to the Configuring Your MCE IR Remote post. I have assigned the “Clear” button to download meta data for videos when in the video manager. This is far quicker than pressing “i” and scrolling through menus and means you can get all the cover / fan art and synopsis with one key press.
Update to Configuring Your MCE IR Remote - Getting Meta Data Fast
January 4th, 2010Acer Aspire Revo - A cheap HD frontend?
August 12th, 2009
Was tipped off about this fantastic article from a recent Ubuntu Uk Podcast. The hardware looks pretty interesting an could make a great HD frontend for MythTV with VDPAU enabled. There’s a good post about trying VDPAU in MythBuntu on the forums but I haven’t had a chance to try it yet as I don’t have one of the supported GPUs.
Anyway, just thought the article was so good it was worth pointing out for anyone that might be looking for a cheap, near silent HD frontend.
Update to Configuring Your MCE IR Remote
August 11th, 2009Just made a quick update to the Configuring Your MCE IR Remote post. I have added in Audio Delay + and - to the mplayer lirc config. This allows you to control the audio / video sync with the Blue and Yellow buttons on your MCE remote. I had quite a few films that have the audio out of sync so this can now be sorted without reaching for the keyboard
Normalise Movie Volume
March 27th, 2009I know DTS is all the rage at the moment but some DTS soundtracks have VERY LOUD LOUD BITS and very quiet quiet bits. This is great for the cinema or those people lucky enough to live in a detached house, but for my 2 bed flat it’s a bit over the top. To level things out mplayer can normalise your movie’s volume in realtime so that explosions are at the same volume as conversations. To enable normalisation add the following switch to the launch command for mplayer:
-af volnormSo for example on your frontend navigate to “Utilities / Setup” -> “Setup” -> “Media Settings” -> “Video Settings” -> “Player Settings” and set the “Default Video Player” to:
mplayer -fs -zoom -quiet -vo xv -subfont-text-scale 3 -af volnorm -cache 8912 -cache-min 4 -lavdopts threads=2:fast:skiploopfilter=all -sws 0 %s
You may find it easier to connect to the mythconverg database and set the VideoDefaultPlayer to the value above for the host machine.
Automatically Convert Radio Shows To MP3 Format
February 15th, 2009It’s great to be able to record radio as well as TV channels using MythTV but to listen to them on an MP3 player they need to be transcoded to MP3 format. The process can be completely automated by setting up a User Job which runs after the show has recorded.
There are four main steps needed to get this going:
1. Install FFmpeg with MP3 encoding support
There’s a great guide for installing FFmpeg with MP3 encoding support here. Just follow it through making sure you use the suggested –enable-libmp3lame switch when running ./configure in step 5.
2. Install libid3-3.8.3-dev for automated ID3 tagging
This library will allow the MP3 encoding script to place ID3 meta tags into the resulting MP3. Info like artist, song and year is set based on the show you are recording.
sudo apt-get install libid3-3.8.3-dev
3. Setup conversion script and MythTV User Job
The script below is the one that is executed by the User Job when the show finishes recording. It is based on this script from the MythTV Wiki but I’ve modified it to work with the latest version of FFmpeg and tag and name the resulting MP3 in my preferred format.
#!/bin/bash ########### # # Suggested execution format in the job settings for the backend (in general of the backend setup) # Remember to allow the job to run in the backend general settings too :) # # autoaudio.sh %FILE% %STARTTIMEISO% "%TITLE%" # ########### OUTPUTDIR="/media/recordedtv/transcoded" INPUTDIR="/media/recordedtv" INFILE=$1 ISODATE=`date +%F` PROGTITLE=$3 STARTDATE=${2:0:10} # Split ########### OUTFILE="$OUTPUTDIR/$PROGTITLE - $STARTDATE.mp3" #transcode mp2 audio to mp3 ffmpeg -i "$INPUTDIR/$INFILE" -acodec libmp3lame -ab 192k -ar 44100 -f mp3 "$OUTFILE" # Tag ########## YEAR=`date +%Y` id3tag --artist="$PROGTITLE" --song="$PROGTITLE - $STARTDATE" --comment="" -y$YEAR -A"Radio" "$OUTFILE"
Copy the script above and put it in a new file in your home directory called autoaudio.sh. For me this was /home/colin/autoaudio.sh. Change the “OUTPUTDIR” and “INPUTDIR” paths to match your setup. “OUTPUTDIR” will be where the MP3 files are created and “INPUTDIR” should be the path to the mpg files of your recorded shows.
Remember to make the script executable.
chmod 777 autoaudio.sh
Also, make sure the MythTV user can write to the output path.
4. Setup the user job
Go into the mythbackend setup and from the menu choose “General” and go to the last screen in this section titled “Job Queue (Job Commands)”. Enter a new job with the description of “Convert to MP3″ then enter the command as below changing the path to the location of your autoaudio.sh file. For me this is
/home/colin/autoaudio.sh %FILE% %STARTTIMEISO% "%TITLE%"
Choose “Finish” so you are back at the mythbackend main menu. Now we need to allow the job to run, so go back into “General” and scroll through to the screen titled “Job Queue (Backend-Specific)”. Tick the box for “Allow Convert to MP3 jobs”. Click “Next” and “Finish” until you are back to the main menu.
All Done
That’s it, you now have a user job which will convert shows to MP3, let’s check it works. I use MythWeb to manage things most of the time. In MythWeb, go to “Recorded Programs”, Click on a show title, then under “Queue a job” click the “Convert to MP3″ button. If all went well you should see an MP3 file created in the output directory you specified in autoaudio.sh. There may be a delay between clicking the button and an MP3 being created depending on how often your mythbackend is set to run user jobs. If nothing is created check the mythbackend logfile at /var/log/mythtv/mythbackend.log for errors.
Once it’s all working it can be activated on an existing recording schedule. In MythWeb, go to “Recording Schedules”, click on a schedule you have setup and look under “Advanced Options”. You should see a tick box for “Convert to MP3″. The show will now be converted to MP3 every time it records.
Updated imdb.pl for getting hi-res movie posters
February 12th, 2009The current version of imdb.pl included with MythTV is not downloading hi-res poster images for movies due to a site change at IMDB’s end. I have edited imdb.pl to include a fix as detailed in https://bugs.launchpad.net/mythbuntu/+bug/256027 and included below.
To get it going, backup your old imdb.pl file in /usr/share/mythtv/mythvideo/scripts/ and replace with:
#!/usr/bin/perl -w # # This perl script is intended to perform movie data lookups based on # the popular www.imdb.com website # # For more information on MythVideo's external movie lookup mechanism, see # the README file in this directory. # # Author: Tim Harvey (tharvey AT alumni.calpoly DOT edu) # Modified: Andrei Rjeousski # v1.1 # - Added amazon.com covers and improved handling for imdb posters # v1.2 # - when searching amazon, try searching for main movie name and if nothing # is found, search for informal name # - better handling for amazon posters, see if movie title is a substring # in the search results returned by amazon # - fixed redirects for some movies on impawards # v1.3 # - fixed search for low res images (imdb changed the page layout) # - added cinemablend poster search # - added nexbase poster search # - removed amazon.com searching for now # changes: # 10-26-2007: # Added release date (in ISO 8601 form) to output # 9-10-2006: Anduin Withers # Changed output to utf8 use LWP::Simple; # libwww-perl providing simple HTML get actions use HTML::Entities; use URI::Escape; eval "use DateTime::Format::Strptime"; my $has_date_format = $@ ? 0 : 1; use vars qw($opt_h $opt_r $opt_d $opt_i $opt_v $opt_D $opt_M $opt_P); use Getopt::Std; $title = "IMDB Query"; $version = "v1.3.5"; $author = "Tim Harvey, Andrei Rjeousski"; my @countries = qw(USA UK Canada Japan); binmode(STDOUT, ":utf8"); # display usage sub usage { print "usage: $0 -hdrviMPD [parameters]\n"; print " -h help\n"; print " -d debug\n"; print " -r dump raw query result data only\n"; print " -v display version\n"; print " -i display info\n"; print "\n"; print " -M [options] <query> get movie list\n"; print " some known options are:\n"; print " type=[fuzy] looser search\n"; print " from_year=[int] limit matches to year\n"; print " to_year=[int] limit matches to year\n"; print " sort=[smart] ??\n"; print " tv=[no|both|only] limits between tv and movies\n"; print " Note: multiple options must be separated by ';'\n"; print " -P <movieid> get movie poster\n"; print " -D <movieid> get movie data\n"; exit(-1); } # display 1-line of info that describes the version of the program sub version { print "$title ($version) by $author\n" } # display 1-line of info that can describe the type of query used sub info { print "Performs queries using the www.imdb.com website.\n"; } # display detailed help sub help { version(); info(); usage(); } sub trim { my ($str) = @_; $str =~ s/^\s+//; $str =~ s/\s+$//; return $str; } # returns text within 'data' between 'beg' and 'end' matching strings sub parseBetween { my ($data, $beg, $end)=@_; # grab parameters my $ldata = lc($data); my $start = index($ldata, lc($beg)) + length($beg); my $finish = index($ldata, lc($end), $start); if ($start != (length($beg) -1) && $finish != -1) { my $result = substr($data, $start, $finish - $start); # return w/ decoded numeric character references # (see http://www.w3.org/TR/html4/charset.html#h-5.3.1) decode_entities($result); return $result; } return ""; } # get Movie Data sub getMovieData { my ($movieid)=@_; # grab movieid parameter if (defined $opt_d) { printf("# looking for movie id: '%s'\n", $movieid);} my $name_link_pat = qr'<a href="/name/[^"]*">([^<]*)</a>'m; # get the search results page my $request = "http://www.imdb.com/title/tt" . $movieid . "/"; if (defined $opt_d) { printf("# request: '%s'\n", $request); } my $response = get $request; if (defined $opt_r) { printf("%s", $response); } # parse title and year my $year = ""; my $title = parseBetween($response, "<title>", "</title>"); if ($title =~ m#(.+) \((\d+).*\)#) # Note some years have a /II after them? { $title = $1; $year = $2; } elsif ($title =~ m#(.+) \(\?\?\?\?\)#) { $title = $1; } # parse director my $data = parseBetween($response, ">Director:</h5>", "</div>"); if (!length($data)) { $data = parseBetween($response, ">Directors:</h5>", "</div>"); } my $director = join(",", ($data =~ m/$name_link_pat/g)); # parse writer # (Note: this takes the 'first' writer, may want to include others) $data = parseBetween($response, ">Writers <a href=\"/wga\">(WGA)</a>:</h5>", "</div>"); if (!length($data)) { $data = parseBetween($response, ">Writer:</h5>", "</div>"); } if (!length($data)) { $data = parseBetween($response, ">Writers:</h5>", "</div>"); } my $writer = join(",", ($data =~ m/$name_link_pat/g)); # parse release date my $releasedate = ''; if ($has_date_format) { my $dtp = new DateTime::Format::Strptime(pattern => '%d %b %Y', on_error => 'undef'); my $dt = $dtp->parse_datetime(parseBetween($response, ">Release Date:</h5> ", "<a ")); if (defined($dt)) { $releasedate = $dt->strftime("%F"); } } # parse plot my $plot = parseBetween($response, ">Plot Outline:</h5> ", "</div>"); if (!$plot) { $plot = parseBetween($response, ">Plot Summary:</h5> ", "</div>"); } if (!$plot) { $plot = parseBetween($response, ">Plot:</h5>", "</div>"); } if ($plot) { # replace name links in plot (example 0388795) $plot =~ s/$name_link_pat/$1/g; # replace title links my $title_link_pat = qr!<a href="/title/[^"]*">([^<]*)</a>!m; $plot =~ s/$title_link_pat/$1/g; # plot ends at first remaining link my $plot_end = index($plot, "<a "); if ($plot_end != -1) { $plot = substr($plot, 0, $plot_end); } $plot = trim($plot); } # parse user rating my $userrating = parseBetween($response, ">User Rating:</b>", "</b>"); $userrating = parseBetween($userrating, "<b>", "/"); # parse MPAA rating my $ratingcountry = "USA"; my $movierating = trim(parseBetween($response, ">MPAA</a>:</h5>", "</div>")); if (!$movierating) { $movierating = parseBetween($response, ">Certification:</h5>", "</div>"); $movierating = parseBetween($movierating, "certificates=$ratingcountry", "/a>"); $movierating = parseBetween($movierating, ">", "<"); } # parse movie length my $rawruntime = trim(parseBetween($response, ">Runtime:</h5>", "</div>")); my $runtime = trim(parseBetween($rawruntime, "", " min")); for my $country (@countries) { last if ($runtime =~ /^-?\d/); $runtime = trim(parseBetween($rawruntime, "$country:", " min")); } # parse cast # Note: full cast would be from url: # www.imdb.com/title/<movieid>/fullcredits my $cast = ""; $data = parseBetween($response, "Cast overview, first billed only", "/table>"); if (!$data) { $data = parseBetween($response, "Series Cast Summary", "/table>"); } if (!$data) { $data = parseBetween($response, "Complete credited cast", "/table>"); } if ($data) { $cast = join(',', ($data =~ m/$name_link_pat/g)); $cast = trim($cast); } # parse genres my $lgenres = ""; $data = parseBetween($response, "<h5>Genre:</h5>","</div>"); if ($data) { my $genre_pat = qr'/Sections/Genres/(?:[a-z ]+/)*">([^<]+)<'im; $lgenres = join(',', ($data =~ /$genre_pat/g)); } # parse countries $data = parseBetween($response, "Country:</h5>","</div>"); my $country_pat = qr'/Sections/Countries/[A-Z]+/">([^<]+)</a>'i; my $lcountries = trim(join(",", ($data =~ m/$country_pat/g))); # output fields (these field names must match what MythVideo is looking for) print "Title:$title\n"; print "Year:$year\n"; print "ReleaseDate:$releasedate\n"; print "Director:$director\n"; print "Plot:$plot\n"; print "UserRating:$userrating\n"; print "MovieRating:$movierating\n"; print "Runtime:$runtime\n"; print "Writers: $writer\n"; print "Cast:$cast\n"; print "Genres: $lgenres\n"; print "Countries: $lcountries\n"; } # dump Movie Poster sub getMoviePoster { my ($movieid)=@_; # grab movieid parameter if (defined $opt_d) { printf("# looking for movie id: '%s'\n", $movieid);} # get the search results page my $request = "http://www.imdb.com/title/tt" . $movieid . "/posters"; if (defined $opt_d) { printf("# request: '%s'\n", $request); } my $response = get $request; if (defined $opt_r) { printf("%s", $response); } if (!defined $response) {return;} my $uri = ""; # look for references to impawards.com posters - they are high quality my $site = "http://www.impawards.com"; my $impsite = parseBetween($response, "<a href=\"".$site, "\">"); if ($impsite) { $impsite = $site . $impsite; if (defined $opt_d) { print "# Searching for poster at: ".$impsite."\n"; } my $impres = get $impsite; if (defined $opt_d) { printf("# got %i bytes\n", length($impres)); } if (defined $opt_r) { printf("%s", $impres); } # making sure it isnt redirect $uri = parseBetween($impres, "0;URL=..", "\">"); if ($uri ne "") { if (defined $opt_d) { printf("# processing redirect to %s\n",$uri); } # this was redirect $impsite = $site . $uri; $impres = get $impsite; } # do stuff normally $uri = parseBetween($impres, "<img SRC=\"posters/", "\" ALT"); # uri here is relative... patch it up to make a valid uri if ($uri =~ /\.(jpe?g|gif|png)$/) { if (!($uri =~ /http:(.*)/ )) { my $path = substr($impsite, 0, rindex($impsite, '/') + 1); $uri = $path."posters/".$uri; } if (defined $opt_d) { print "# found ipmawards poster: $uri\n"; } } else { $uri = ""; } } # try looking on MoTechPosters if ($uri eq "" && $response =~ m/<a href="([^"]*)">([^"]*?)motechposters/i) { if ($1 ne "") { if (defined $opt_d) { print "# found MoTechPosters poster page: $1 \n"; } my $cinres = get $1; if (defined $opt_d) { printf("# got %i bytes\n", length($cinres)); } if (defined $opt_r) { printf("%s", $cinres); } if ($cinres =~ m/<img src="([^"]*?$movieid[^"]*?)"/i) { if (defined $opt_d) { print "# MoTechPosters url retreived\n"; } $uri = "http://posters.motechnet.com".$1; } } } # try looking on nexbase if ($uri eq "" && $response =~ m/<a href="([^"]*)">([^"]*?)nexbase/i) { if ($1 ne "") { if (defined $opt_d) { print "# found nexbase poster page: $1 \n"; } my $cinres = get $1; if (defined $cinres) { if (defined $opt_d) { printf("# got %i bytes\n", length($cinres)); } if (defined $opt_r) { printf("%s", $cinres); } if ($cinres =~ m/<a id="photo_url" href="([^"]*?)" ><\/a>/i) { if (defined $opt_d) { print "# nexbase url retreived\n"; } $uri = $1; } } } } # try looking on cinemablend if ($uri eq "" && $response =~ m/<a href="([^"]*)">([^"]*?)cinemablend/i) { if ($1 ne "") { if (defined $opt_d) { print "# found cinemablend poster page: $1 \n"; } my $cinres = get $1; if (defined $opt_d) { printf("# got %i bytes\n", length($cinres)); } if (defined $opt_r) { printf("%s", $cinres); } if ($cinres =~ m#<img\b[^>]+\bsrc="(/images/reviews/[^"]*?)"#i) { if (defined $opt_d) { print "# cinemablend url retreived\n"; } $uri = "http://www.cinemablend.com/".$1; } } } # if the impawards site attempt didn't give a filename grab it from imdb if ($uri eq "") { if (defined $opt_d) { print "# looking for imdb posters\n"; } my $host = "http://posters.imdb.com/posters/"; $uri = parseBetween($response, $host, "\"><td><td><a href=\""); if ($uri ne "") { $uri = $host.$uri; } else { if (defined $opt_d) { print "# no poster found\n"; } } } my @movie_titles; my $found_low_res = 0; my $k = 0; # no poster found, take lowres image from imdb if ($uri eq "") { if (defined $opt_d) { print "# looking for lowres imdb posters\n"; } my $host = "http://www.imdb.com/title/tt" . $movieid . "/"; $response = get $host; # Better handling for low resolution posters # if ($response =~ m/<a name="poster".*<img.*src="([^"]*).*<\/a>/ig) { if (defined $opt_d) { print "# found low res poster at: $1\n"; } $uri = $1; $found_low_res = 1; } else { if (defined $opt_d) { print "# no low res poster found\n"; } $uri = ""; } if (defined $opt_d) { print "# starting to look for movie title\n"; } # get main title if (defined $opt_d) { print "# Getting possible movie titles:\n"; } $movie_titles[$k++] = parseBetween($response, "<title>", "<\/title>"); if (defined $opt_d) { print "# Title: ".$movie_titles[$k-1]."\n"; } # now we get all other possible movie titles and store them in the titles array while($response =~ m/>([^>^\(]*)([ ]{0,1}\([^\)]*\)[^\(^\)]*[ ]{0,1}){0,1}\(informal title\)/g) { $movie_titles[$k++] = trim($1); if (defined $opt_d) { print "# Title: ".$movie_titles[$k-1]."\n"; } } } print "$uri\n"; } # dump Movie list: 1 entry per line, each line as 'movieid:Movie Title' sub getMovieList { my ($filename, $options)=@_; # grab parameters # If we wanted to inspect the file for any reason we can do that now # # Convert filename into a query string # (use same rules that Metadata::guesTitle does) my $query = $filename; $query = uri_unescape($query); # in case it was escaped # Strip off the file extension if (rindex($query, '.') != -1) { $query = substr($query, 0, rindex($query, '.')); } # Strip off anything following '(' - people use this for general comments if (rindex($query, '(') != -1) { $query = substr($query, 0, rindex($query, '(')); } # Strip off anything following '[' - people use this for general comments if (rindex($query, '[') != -1) { $query = substr($query, 0, rindex($query, '[')); } # IMDB searches do better if any trailing ,The is left off $query =~ /(.*), The$/i; if ($1) { $query = $1; } # prepare the url $query = uri_escape($query); if (!$options) { $options = "" ;} if (defined $opt_d) { printf("# query: '%s', options: '%s'\n", $query, $options); } # get the search results page # some known IMDB options are: # type=[fuzy] looser search # from_year=[int] limit matches to year (broken at imdb) # to_year=[int] limit matches to year (broken at imdb) # sort=[smart] ?? # tv=[no|both|only] limits between tv and movies (broken at imdb) #$options = "tt=on;nm=on;mx=20"; # not exactly clear what these options do my $request = "http://www.imdb.com/find?q=$query;$options"; if (defined $opt_d) { printf("# request: '%s'\n", $request); } my $response = get $request; if (defined $opt_r) { print $response; exit(0); } # check to see if we got a results page or a movie page # looking for 'add=<movieid>" target=' which only exists # in a movie description page my $movienum = parseBetween($response, "add=", "\""); if (!$movienum) { $movienum = parseBetween($response, ";add=", "'"); } if ($movienum) { if ($movienum !~ m/^[0-9]+$/) { if (defined $opt_d) { printf("# Error: IMDB movie number ($movienum), isn't.\n"); } exit(0); } if (defined $opt_d) { printf("# redirected to movie page\n"); } my $movietitle = parseBetween($response, "<title>", "</title>"); $movietitle =~ m#(.+) \((\d+)\)#; $movietitle = $1; print "$movienum:$movietitle\n"; exit(0); } # extract possible matches # possible matches are grouped in several catagories: # exact, partial, and approximate my $popular_results = parseBetween($response, "<b>Popular Titles</b>", "</table>"); my $exact_matches = parseBetween($response, "<b>Titles (Exact Matches)</b>", "</table>"); my $partial_matches = parseBetween($response, "<b>Titles (Partial Matches)</b>", "</table>"); # my $approx_matches = parseBetween($response, "<b>Titles (Approx Matches)</b>", # "</table>"); # parse movie list from matches my $beg = "<tr>"; my $end = "</tr>"; my $count = 0; my @movies; # my $data = $exact_matches.$partial_matches; my $data = $popular_results.$exact_matches; # resort to partial matches if no exact if ($data eq "") { $data = $partial_matches; } # resort to approximate matches if no exact or partial # if ($data eq "") { $data = $approx_matches; } if ($data eq "") { if (defined $opt_d) { printf("# no results\n"); } return; } my $start = index($data, $beg); my $finish = index($data, $end, $start); my $year; my $type; my $title; while ($start != -1 && $start < length($data)) { $start += length($beg); my $entry = substr($data, $start, $finish - $start); $start = index($data, $beg, $finish + 1); $finish = index($data, $end, $start); my $title = ""; my $year = ""; my $type = ""; my $movienum = ""; # Some titles are identical, IMDB indicates this by appending /I /II to # the release year. # e.g. "Mon meilleur ami" 2006/I vs "Mon meilleur ami" 2006/II if ($entry =~ m/<a href="\/title\/tt(\d+)\/.*\">(.+)<\/a> \((\d+)\/?[a-z]*\)(?: \((.+)\))?/i) { $movienum = $1; $title = $2; $year = $3; $type = $4 if ($4); } else { if (defined $opt_d) { print("Unrecognized entry format ($entry)\n"); } next; } my $skip = 0; # fix broken 'tv=no' option if ($options =~ /tv=no/) { if ($type eq "TV") { if (defined $opt_d) {printf("# skipping TV program: %s\n", $title);} $skip = 1; } } if ($options =~ /tv=only/) { if ($type eq "") { if (defined $opt_d) {printf("# skipping Movie: %s\n", $title);} $skip = 1; } } # fix broken 'from_year=' option if ($options =~ /from_year=(\d+)/) { if ($year < $1) { if (defined $opt_d) {printf("# skipping b/c of yr: %s\n", $title);} $skip = 1; } } # fix broken 'to_year=' option if ($options =~ /to_year=(\d+)/) { if ($year > $1) { if (defined $opt_d) {printf("# skipping b/c of yr: %s\n", $title);} $skip = 1; } } # option to strip out videos (I think that's what '(V)' means anyway?) if ($options =~ /video=no/) { if ($type eq "V") { if (defined $opt_d) { printf("# skipping Video program: %s\n", $title); } $skip = 1; } } # (always) strip out video game's (why does IMDB give these anyway?) if ($type eq "VG") { if (defined $opt_d) {printf("# skipping videogame: %s\n", $title);} $skip = 1; } # add to array if (!$skip) { my $moviename = $title; if ($year ne "") { $moviename .= " ($year)"; } # $movies[$count++] = $movienum . ":" . $title; $movies[$count++] = $movienum . ":" . $moviename; } } # display array of values for $movie (@movies) { print "$movie\n"; } } # # Main Program # # parse command line arguments getopts('ohrdivDMP'); # print out info if (defined $opt_v) { version(); exit 1; } if (defined $opt_i) { info(); exit 1; } # print out usage if needed if (defined $opt_h || $#ARGV<0) { help(); } if (defined $opt_D) { # take movieid from cmdline arg $movieid = shift || die "Usage : $0 -D <movieid>\n"; getMovieData($movieid); } elsif (defined $opt_P) { # take movieid from cmdline arg $movieid = shift || die "Usage : $0 -P <movieid>\n"; getMoviePoster($movieid); } elsif (defined $opt_M) { # take query from cmdline arg $options = shift || die "Usage : $0 -M [options] <query>\n"; $query = shift; if (!$query) { $query = $options; $options = ""; } getMovieList($query, $options); } # vim: set expandtab ts=3 sw=3 :
Quickly Sort Channels
February 11th, 2009Something that’s not quite perfect in MythTV is sorting channels. You can move channels around one by one in the backend setup screens but this is slow and boring. A quicker way is to update the channel table in the mythconverg database on your backed. I had a search around and found this useful post on the Ubuntu forms but it was still a pain to have to adjust the SQL strings as they were. My solution is to put the SQL into to a spreadsheet (attached below):
Channel Order Helper Spreadsheet
Obviously your channel listing is going do be different to mine so I suggest you do the following:
- Download the spreadsheet
- Get your existing channel names by running:
SELECT DISTINCT name FROM channel ORDER BY LPAD(channum, 3, 0) ASC;
- Paste them into column D in the spread sheet
- Re-arrange as required
- Select all the cells and copy into gedit or similar (removing any tabs)
- Run all statements agains your mythconverg database.
NB. This will update the channel numbers for all sources (you could always change the sql to include a “WHERE sourceid = 1″ clause or simialr. Also, make sure that your frontend is set to sort by “Channel Number” in “Utilities/Setup” -> “Setup” -> “TV” -> “Settings” -> “General”
Play 720p HD Content Over Wireless & Make The Subtitle Size Sensible
February 9th, 2009This one drove me nuts for a while, watching 720p content over 54Mbit/s wi-fi should work fine but with the “out of the box” settings HD moves were stuttering terribly for me.
As an additional niggle, embedded subtitles were appearing but they were enormous.
By default MythTV uses mplayer for mkv, avi and mpeg files. To resolve the stutter and subtitle issue open the MythTV frontend and go to “Utilities / Setup” -> “Setup” -> “Media Settings” -> “Video Settings” -> “Player Settings” and set the “Default Video Player” to:
mplayer -fs -zoom -quiet -vo xv -subfont-text-scale 3 -cache 8912 -cache-min 4 -lavdopts threads=2:fast:skiploopfilter=all -sws 0 %s
You may find it easier to connect to the mythconverg database and set the VideoDefaultPlayer to the value above for the host machine on wireless.
Time to get public
February 9th, 2009After many months of tweaking, hacking and generally abusing MythTv to behave the way I’d like (and be girlfriend friendly) I though it was about time to publish some of the things that have helped me.
Who knows how often I’ll update this blog but the current plan is just to add things as and when I discover them in the hope that it helps you too!
If you are new to MythTv check out the About page for general info and links.
Let the tips commence…
