Dvb grabber.pl

From MythTV Official Wiki
Jump to: navigation, search

Author Bob
Description Perl script to grab 5 seconds from unencrypted DVB channels
Supports


dvb_grabber.pl

Given a configuration file that matches the 'scan' program from linux-dvb, this script will output a file for each channel it can successfully capture.

Command line usage

perl dvb_grabber.pl -a 0 -f scan.conf

where the -a option is the DVB tuner ID and the -f option is the configuration file. This script will create a file name CXXX-YY.ts for each stream captured.

Dependencies

This program requires azap (from linux-dvb) and mplayer. It could be re-written to use ffmpeg instead of mplayer.

The Code

Script.png fix_scan_chan.pl

#!/usr/bin/perl

# Version 1.0 - Jul 7, 2010

use Getopt::Std;
use strict;

my($cf, $adapter, $fn, @fields, $chan, $azap_pid, $cat_pid, $pkt, $i, $pid,
   $name, $height, $width, %opts);

$cf = $ENV{'HOME'} . "/.azap/channels.conf";
$adapter = 1;
getopts('a:f:', \%opts);
foreach (keys %opts) {
  $adapter = int($opts{$_}) if($_ =~ m/a/);
  $cf = $opts{$_} if($_ =~ m/f/);
}

open F, $cf || die "failed to open $cf: $!";
while(<F>) {
    @fields = split /:/, $_;
    $name = $fields[0];
    $fn = $name . ".ts";
    unlink "$fn" if(-e "$fn");
    print "capturing $name ...";
    # Start azap to tune desired channel
    $azap_pid = fork();
    if(! defined $azap_pid ) {
        die "fork() failed: $!";
    } elsif($azap_pid == 0) {
        # Child process, exec azap
        close(STDERR);
        close(STDOUT);
        exec("azap -c $cf -a $adapter -r $name");
        exit(0);
    }
    # Wait for azap to tune
    select undef, undef, undef, 1.0;
    # Azap running, fork and cat device to get transport stream
    $cat_pid = fork();
    if(! defined $cat_pid ) {
        die "fork() failed: $!";
    } elsif($cat_pid == 0) {
        close(STDERR);
        close(STDOUT);
        # Child process, copy from device file to output file
        $i = 20;
        while($i > 0) {
            last if(open FHI, "< /dev/dvb/adapter${adapter}/dvr0");
            $i--;
            select undef, undef, undef, 0.25;
        }
        open FHO, "> $fn";
        while(1) {
            sysread FHI, $pkt, 188;
            syswrite FHO, $pkt;
        }
        exit(0);
    }
    # Wait for enough data to be captured
    sleep 5;
    kill 1, $cat_pid;
    kill 1, $azap_pid;
    # Reap children
    $i = 10;
    while($i > 0) {
        $pid = wait();
        last if($pid == -1);
        $i--;
    }
    if($i < 1) {
        print "too many wait() attempts ";
    }
    if(! -e "$fn") {
        print "no file, channel gone?\n";
        next;
    }
    if(-s $fn < 1) {
       unlink $fn;
       print  "0 bytes\n";
       next;
    }
    undef $height;
    undef $width;
    if(open P, "mplayer -really-quiet -identify $fn -ao null -vo null -frames 0  2>/dev/null |") {
        while(<P>) {
            if($_ =~ m/ID_VIDEO_WIDTH=(.+)/) {
                $width = $1;
            }
            if($_ =~ m/ID_VIDEO_HEIGHT=(.+)/) {
                $height = $1;
            }
            next;
        }
        close(P);
    }
    if(! defined $width || ! defined $height) {
        print " encrypted\n";
        unlink $fn;
        next;
    }
    print $width . "x" . $height . "\n";
}