PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Videos aufnehmen mit mencoder



palm-man
07.11.04, 22:13
Hallo,

Ihr kennt das sicher: Im Fernsehen läuft ein toller Film, und Ihr wollt ihn aufnehmen, und zwar möglichst schnell und problemlos. Den PC als digitalen Videorekorder nutzen, auch wenn er nur von der TV-Karte aufnimmt.

Ihr kennt auch Hunters Howto zur TV-Aufnahme (http://www.linuxforen.de/forums/showthread.php?t=88454), wollt es aber gerne noch einfacher.

Am besten sollte das aufgenommene Video gleich komprimiert sein.

Dann seid Ihr hier richtig.

Ihr braucht:

Den XviD-Codec (http://xvid.org)
Mencoder (http://mplayerhq.hu) (Teil von Mplayer)
Scantv (http://linux.bytesex.org/xawtv/) (Teil von XawTV)


Und dazu noch einen einigermaßen flotten Rechner. Ich nehme erfolgreich mit einem Athlon XP 1800+ auf.

Eure TV-Karte habt Ihr schon eingerichtet und, wie in Hunters Howto beschrieben, einen Eintrag für Eure TV-Karte in der /etc/modules.conf bzw. /etc/modprobe.conf vorgenommen ("gbuffers=16").

Zuerst scannen wir die TV-Kanäle. Dafür gibt's das Programm "scantv", ruft es mit root-Rechten auf, damit es die Datei /etc/tvchannels schreiben kann:

$ scantv -o /etc/tvchannels
please select your TV norm
0: PAL
[...]
nr ? 0

please select a frequency table
[...]
5: europe-west
[...]
nr ? 5

[...]

Wenn das Programm abgearbeitet ist, habt Ihr in der Datei /etc/tvchannels eine Senderliste gespeichtert, die Ihr z.B. auch für XawTV nutzen könnt. Der Aufbau ist sehr einfach. In den eckigen Klammern steht der Sendername, darunter der Kanal.

Jetzt braucht Ihr dieses kleine Script (auch im Anhang):


#!/bin/bash
# bash script to capture videos from tv using mencoder
#
# usage: capture CHANNELNAME [BITRATE [WIDTH [HEIGHT]]]
#
# 2004, Tino Wagner <ich@tinowagner.com>

# DEFINE! the path to a channel list (created by scantv)
channellist="/etc/tvchannels"

# find out the channel number
channel=$(
egrep -i -A 1 "\[$1\]" "$channellist" |
tail -n 1 |
cut -c 11-
)
if [ -z "$channel" ] ; then
echo "Channel not found."
exit 1
fi
echo "Using channel $channel for $1."

# delete spaces from channel name
channelname=$(
echo "$1" |
tr -d "[:blank:]"
)
echo "Channel's name: $channelname"

# bitrate
bitrate=$2
[ -z "$bitrate" ] && bitrate=1500
echo "Using bitrate: $bitrate"

# resolution
width=$3
[ -z "$width" ] && width=576
height=$4
if [ -z "$heigth" ] ; then
height=$[$width/4*3];
fi
echo "Using resolution: $width x $height"

# save the start time
starttime=$(date +%Y%m%d-%H%M)
# save start time stamp
startstamp=$(date +%s)

# do the magic :o)

mencoder -cache 50000 -ovc xvid -oac mp3lame -xvidencopts bitrate=$bitrate -vf lavcdeint -tv driver=v4l2:chanlist=europe-west:width=$width:height=$height tv://$channel -o temp.avi

# save stop time stamp
stopstamp=$(date +%s)

# construct a filename
filename="$channelname-$starttime-$[$stopstamp-$startstamp]s.avi"

# rename the temporary video file
mv temp.avi "$filename"
echo "Video saved: $filename"


Das Script speichert Ihr am besten unter dem Namen "capture" unter /usr/local/bin/.

Die Zeile, die "mencoder" aufruft, ist für die Aufnahme verantwortlich. Standardmäßig wird das Video on-the-fly mit XviD komprimiert, der Ton wird mp3-komprimiert. Auch wird ein Deinterlace-Filter über den Videostrom gejagt: der macht aus den Halbbildern des Fernsehers wieder Vollbilder.
Ihr könnt sie aber auch Euren Wünschen anpassen. Also andere Codecs verwenden oder andere Filter benutzen.

Wenn Ihr nun etwas im Fernsehen aufnehmen wollt, beendet Ihr die TV-Applikation (Tvtime, XawTV) und ruft das Script auf:

$ capture [sendername]

Das war's schon. Den jeweiligen Sendernamen entnehmt Ihr bitte der Datei /etc/tvchannels. Wenn der Sendername aus mehreren Wörtern besteht, müßt Ihr ihn in Anführungszeichen setzen, z.B.: capture "Pro Sieben".

Man kann dem Script alternativ noch ein paar Parameter übergeben, z.B. die Bitrate des Videos (gleich nach dem Sendernamen) oder Videogröße (Bildbreite nach der Bitrate, Bildhöhe wird automatisch errechnet, wenn sie nicht angegeben wird).

Wollt Ihr ein Sendung aufnehmen, die auf ZDF läuft, sie mit einer Bitrate von 1000 kbit/s komprimieren, dabei die Bildgröße auf 352 Pixel beschränken, so gebt Ihr ein:


$ capture ZDF 1000 352


Wenn die Sendung vorüber ist oder Ihr die Aufnahme abbrechen wollt, drückt Ihr [CTRL]-[C]. Damit wird Mencoder beendet.

Das Script speichert das Video dann im aktuellen Verzeichnis ab. Der Dateiname setzt sich zusammen aus dem Sendernamen, dem Datum, der Uhrzeit und der Aufnahmelänge in Sekunden.

Ihr könnt auch zeitgesteuert aufnehmen. Dafür braucht Ihr dann das Programm "at", ist für jede anständige Distribution verfügbar. Atd muß laufen.

Läuft abends wieder "Wer wird Millionär" auf RTL, gebt Ihr ein:


$ at 20:14 today
at> cd /home/benutzer/aufnahmen && capture RTL
at> [CTRL]-[D] <EOT>
$ at 21:16 today
at> killall mencoder
at> [CTRL]-[D] <EOT>


Damit habt Ihr zwei Jobs gestartet, einer beginnt die Aufnahme (wechselt aber noch in ein Aufnahmeverzeichnis), der andere stoppt die Aufnahme, indem er mencoder tötet.

Viel Spaß damit.
Anregungen bitte per PM.

:)

djtm
10.11.04, 11:26
Ein schönes TV-Programm, das all das und mehr kann ist Xdtv:
http://xawdecode.sf.net/

Es kann
Live aufnehmen und gleichzeitig ansehen
Deinterlacen (Linear Blend, Greedy, etc.)
Als Videorecorder fungieren (xawdecode_record.sh)
Video als X-Vid, FFmpeg, Huffyuv, Unkomprimiert aufnehmen.
Audio unkomprimiert oder als MP3.
Streamen.
ScreenShots machen
Kanäle bearbeiten
...


Viel Spaß damit!

carnil
24.03.05, 16:14
Hallo

Ich habe von fork (http://www.linuxforen.de/forums/member.php?userid=6777) eine PN erhalten, mit der Bitte, diese - von fork erweiterte - Version den Skriptes an den Beitrag anzuhängen.


#!/bin/bash
# bash script to capture videos from tv using mencoder
#
# usage: capture CHANNELNAME [BITRATE [WIDTH [HEIGHT]]]
#
# Creator: 2004, Tino Wagner <ich(at)tinowagner(dot)com>
# Update: 2005, Tobias Unsleber <tobias.unsleber(at)gmx(dot)net>

# DEFINE! the path to a channel list (created by scantv)
channelfile="/etc/channels.txt"

TMP_DIR=$HOME
DST_DIR=$TMP_DIR

DEFAULT_BITRATE=1500
DEFAULT_WIDTH=576

function usage {

echo "$(basename $0) [ -r<rectime> | --rectime=<rectime> ] [ -b<bitrate> | --bitrate=<bitrate> ] [ -x<width> | --width=<width> ] [ -y<height> | --height=<height> ] [ -? | -h | --help ] <channel>


channel : Channel name in channel file( $channelfile )
-r|--rectime : recording time in Format hh:mm:ss, if not given,
record until keyboard request (Ctrl + C)
-b|--bitrate : in kb/sec defaults to 1500
-x|--width : recording width, defaults to 576
-y|--height : recording height, defaults to 4/3 * width
-h|--help : print this usage " ;

}

TEMP=`getopt -o r:b:x:y:h --long rectime:,width:,height:,help \
-n $(basename $0) -- "$@"`

ec=$?
if [ $ec != 0 ] ; then echo "Error(errcode=$ec) while parsing Command line..." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
case "$1" in
-r|--rectime) # echo "requested recording time : $2"
rectime=$2
shift 2 ;;

-b|--bitrate) # echo "requested bitrate : $2"
bitrate=$2
shift 2 ;;

-x|--width) # echo "requested width : $2"
width=$2
shift 2 ;;

-y|--height) #echo "requested height : $2"
height=$2
shift 2 ;;

-h|--help) usage ; exit 0 ;;

--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done

# Getting Channel
argc=0
for arg do channel=$arg;((argc++)); done
if [ $argc -ne 1 ] ;then echo -e "\nwrong parameter count\n" ; usage ; exit 1; fi

echo ""
# find out the channel number
channel=$(
egrep -i -A 1 "\[$channel\]" "$channelfile" |
tail -n 1 |
cut -c 11-
)
if [ -z "$channel" ] ; then
echo "Channel not found."
exit 1
fi
echo "Using channel $channel for $1."

# delete spaces from channel name
channelname=$(
echo "$1" |
tr -d "[:blank:]"
)
echo "Channel's name: $channelname"

# bitrate
[ -z "$bitrate" ] && bitrate=$DEFAULT_BITRATE
echo "Using bitrate: $bitrate"

# recording time
if [ -n "$rectime" ]
then
opt_rectime="-endpos $rectime"
echo "Recording duration: $rectime"
fi


# resolution
[ -z "$width" ] && width=$DEFAULT_WIDTH
if [ -z "$heigth" ] ; then
height=$[$width/4*3];
fi
echo "Using resolution: $width x $height"

# save the start time
starttime=$(date +%Y%m%d-%H%M)
# save start time stamp
startstamp=$(date +%s)

# do the magic :o)

echo
mencoder -quiet -cache 50000 -ovc lavc -oac lavc -lavcopts acodec=mp3:abitrate=320:vcodec=mpeg4:vbitrate=$bit rate -vf lavcdeint -tv driver=v4l2:chanlist=europe-west:width=$width:height=$height tv://$channel $opt_rectime -o "$TMP_DIR"/temp.avi >/dev/null
#mencoder -cache 50000 -ovc xvid -oac mp3lame -xvidencopts bitrate=$bitrate -vf lavcdeint -tv driver=v4l2:chanlist=europe-west:width=$width:height=$height tv://$channel $opt_rectime -o "$TMP_DIR"/temp.avi

# save stop time stamp
stopstamp=$(date +%s)

# construct a filename
filename="$channelname-$starttime-$[$stopstamp-$startstamp]s.avi"

# rename the temporary video file
mv "$TMP_DIR/temp.avi" "$DST_DIR/$filename"
echo "Video saved: $DST_DIR/$filename"

MfG carnil