Use GNU/Linux to play TV programs
At present, many things in life can be completed in front of the computer, reading books, writing programs, listening to music, watching videos, etc. It would be better if you could watch cable TV programs on your computer. For this reason, I purchased the yuangang video capture card AverMedia C725B. As shown in.
The official introduction to this card is as follows ):
The C725 SD card is a PCI-E acquisition card that supports AV terminals, s terminals and stereo input. It can digitize analog formats such as PAL, NTSC and SECAM, extract and save the file as an uncompressed AVI file. The software development kit (SDK) attached to the C725 SD card provides common functions to help developers or system integrators complete their work easily and efficiently. In addition, This SDK is compatible with mainstream programming languages such as Visual C ++ and Visual Basic, making it easier for developers to get started.
Officially claimed to support Linux, and the driver needs to be requested from it. The website does not provide download. However, it is hard to say whether AverMedia C725 can really work on its own Debian Wheezy (3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux, I had to take some chances to try it out.
After installing the AverMedia pcicard, contact the official website to obtain the driver. Note that you must obtain the same driver as your Linux kernel version. Otherwise, compilation may fail. After I tried the driver provided by the official default for the old kernel version, I asked yuangang's technicians to re-compile a new version for Linux 3.2.51. With the official driver, install the linux-source package and the linux-headers package to compile the driver. First, export the environment variable C_INCLUDE_PATH, which contains the dvb-related files provided by linux-source:
export C_INCLUDE_PATH=/usr/include/:/usr/src/linux-source-3.2/drivers/media/dvb/dvb-core/:/usr/src/linux-source-3.2/drivers/media/dvb/frontends/
The subsequent compilation process is usually the three steps of make, and everything goes smoothly.
With the hardware foundation, I chose to use mplayer for the TV playing software, and the video recording was mencoder. Due to the many parameters required by the command line, I wrote a script program rtv. sh to conveniently play or record programs. By specifying the command line parameters watch, nowatch, and onlywatch, the script can be run in three modes:
- Watch: saves the video as an avi file while playing the TV;
- Nowatch: only the recorded program is saved as an avi file and is not played in real time;
- Onlywatch: Watch the program with only mplayer instead of recording.
The script uses the following programs:
- Mencoder: Obtain the video stream from the video capture card in the specified format and output it to a namefifo pipeline (named FIFO pipe );
- Tee: Retrieves data streams from the standard input and then redirects them to the standard output. The pipe line can be used to take the content of the FIFO pipe as the standard input of the tee command, and the standard output of the tee command can be played as the standard input of the mplayer program. In addition, the tee command can use the command line parameter-a filename. In this way, when the data stream is sent to the standard output or mplayer, it is saved to the specified file. With this mechanism, you can play and record TV programs at the same time;
- Mplayer: Play video streams transferred from tee.
The execution process of the script program is: first check the user's command line parameter input, and then check whether the mencoder, tee, and mplayer processes are running. If the program already exists, it indicates that the program has been played or recorded, prompting the user to exit. Otherwise, execute the following process:
- First, use mkfifo to create a name FIFO pipe/tmp/TV. fifo;
- Second, use the cat command to output the content of the MPs queue to the standard output, and use the MPs queue to output the output as the standard input of the tee command. In the recording and playback mode (watch), it is divided into two ways, one way to send to the avi file, one way to the mplayer for playing; in nowatch mode, only the avi file is output. in pure playback mode (onlywatch), only the video is sent to mplayer.
- Finally, use mencoder to capture video streams from the AverMedia C725B acquisition card on the device node/dev/video0 in the system, and output the video streams in the specified format to the name pipeline created earlier.
The source code of the script program is:
#! /Bin/bash
Script_name = "rtv. sh"
Script_usage = $ (cat <EOF
Rtv MODE [FILE]
EOF
)
Script_function = $ (cat <EOF
Record or watch TV. MODE can be 'Watch ', 'onlywatch', 'nowatch '. When 'Watch' or 'nowatch 'is specified, the file name must be provided.
EOF
)
Script_doc = $ (cat <EOF
-H Display this help.
EOF
)
Script_examples = $ (cat <EOF
Rtv nowatch test. avi
Rtv watch test. avi
Rtv onlywatch
EOF
)
State_prefix = "="
Warning_prefix = "***"
Error_prefix = "!!! "
Function display_help (){
If [-n "$ script_usage"]; then
Echo-e "Usage: $ script_usage"
Fi
If [-n "$ script_function"]; then
Echo-e "$ script_function"
Fi
If [-n "$ script_doc"]; then
Echo-e "\ n $ script_doc"
Fi
If [-n "$ script_examples"]; then
Echo-e "\ nExamples"
Echo-e "$ script_examples"
Fi
}
# Process command options
While getopts ": h" opt; do
Case $ opt in
H) display_help
Exit 0 ;;
\? ) Display_help
Exit 1 ;;
Esac
Done
Shift $ ($ OPTIND-1 ))
# Define a function for returning a process id
Function get_pid_by_name ()
{
Local process_str
Echo "Searching process $1 ..."
Process_str = 'ps aux | grep "$1" | tr -- squeeze-repeats '[: blank:] + ''\ T' | cut-f 2'
If [-n "$ process_str"]; then
# The process for grep appears in the second field
Process_str = 'echo $ process_str | cut-s-d ''-f 1'
If [-n "$ process_str"]; then
Temp_pid = $ process_str
Echo "The process id is $ temp_pid! "
Else
Echo "The process $1 cannot be found, perfect! "
Fi
Else
Echo "The process $1 cannot be found, perfect! "
Fi
}
# Start execute the command
If [$ OSTYPE = 'linux-gnu '] & ['hostname' = "QuantumHome"]; then
If [-z "$1"]; then
Echo "$ error_prefix Please specify the recording and watching mode: watch | nowatch | onlywatch"
Exit 0
Fi
If ["$1 "! = "Onlywatch"] & [-z "$2"]; then
Echo "$ error_prefix Please provide the video file name to be saved! "
Exit 0
Fi
# Declare the pid as integers
Declare-I temp_pid =-1 mplayer_pid =-1 mencoder_pid =-1 tee_pid =-1
Get_pid_by_name mencoder
Mencoder_pid = $ temp_pid
Temp_pid =-1
Get_pid_by_name tee
Tee_pid = $ temp_pid
Temp_pid =-1
Get_pid_by_name mplayer
Mplayer_pid = $ temp_pid
Temp_pid =-1
If [$ ($ mencoder_pid! =-1 & $ mplayer_pid! =-1 & $ tee_pid! =-1) = 1]; then
Echo "$ error_prefix A TV recording or watching activity is now working, please exit it first! "
Exit 0
Fi
# Create FIFO named pipe
If [! -E "/tmp/TV. fifo"]; then
Echo "$ state_prefix FIFO does not exist, now being created ..."
Mkfifo/tmp/TV. fifo & echo "$ state_prefix Creating FIFO successful! "
Fi
# Start tee and mplayer
Case "$1" in
Watch) echo "$ state_prefix Start recording TV and watch it using mplayer ..."
# Note: sudo must be used in order to make mplayer appear
Cat/tmp/TV. fifo | tee-a "$ {2%. avi }. avi "| sudo-u orlando DISPLAY =: 0.0 mplayer-cache 51200-frameddrop-ao sdl-vo xv -&;;
Nowatch) echo "$ state_prefix Start recording TV without watching it ..."
Cat/tmp/TV. fifo | tee-a "$ {2%. avi}. avi "&;;
Onlywatch) echo "$ state_prefix Start watching TV without recording it ..."
# Note: "tee-a-" will not work here
Cat/tmp/TV. fifo | tee | sudo-u orlando DISPLAY =: 0.0 mplayer-cache 51200-frameddrop-ao sdl-vo xv -&;;
*) Echo "$ error_prefix Please specify the recording and watching mode: watch | nowatch | onlywatch"
Exit 0;
Esac
# Start mencoder to feed the video stream into FIFO
Echo "$ state_prefix Now start mencoder to capture TV ..."
Mencoder TV: //-TV driver = v4l2: device =/dev/video0: norm = PAL: alsa: adevice = hsf-2, 0: amode = 1: audiorate = 48000: forceaudio: volume = 100: immediatemode = 0: normid = 8: input = 1: buffersize = 1024: width = 768: height = 576: outfmt = i420-oac mp3lame-lameopts fast: preset = standard-ovc lavc-lavcopts vcodec = mpeg4: vhq: vbitrate = 1800-o/tmp/TV. fifo
Else
Echo "$ warning_prefix Operating system or host name is not supported! "
Fi
In this script, the mencoder parameters are more complex. Here we will explain them as follows:
- Driver = v4l2: use the video for linux driver;
- Device =/dev/video0: video card device node. This node appears only when the driver is correctly installed;
- Norm = PAL: Specifies the analog TV system. China is PAL;
- Alsa: capture audio from ALSA;
- Adevice = hsf-2, 0: Specifies the audio device. When the OSS audio system is used, the value of adevice is/dev/xxx. When the ALSA audio system is used, the value is the hardware ID, such as hw. Note that, because the command line cannot contain a colon, replace the colon in hw: 2, 0 with a comma;
- Amode = 1: Specifies the sound mode. 0 is single channel, 1 is stereo;
- Audiorate = 48000: input audio sampling rate;
- Forceaudio: forcibly collects audio, even if no audio source is available in the v4l library;
- Volume = 100: Specifies the volume of the mixer on the video capture card;
- Immediatemode = 0: 0 indicates that audio and video streams are collected and cached at the same time (default value of mencoder). 1 indicates that only video streams are collected, however, audio streams are sent to the Sound Card (default value of mplayer) through a loop-back route ). Because I use mencoder, set it to 0;
- Normid = 8: TV standard number of the acquisition card;
- Buffersize = 1024: size of the collection buffer, in MB
- Width = 768: height = 576: width and height of the output video pixel;
- Outfmt = i420: Output video data format;
- -Oac mp3lame: Specifies the Audio Encoder as mp3lame;
- -Lameopts fast: preset = standard: Specifies the Audio Encoder option;
- -Ovc lavc: Specifies the video encoder as libavcodec;
- -Lavcopts vcodec = mpeg4: vhq: vbitrate = 1800: Specifies the video encoder option.
It should be noted that the avi files recorded by rtv. sh do not have an index, so you cannot fast forward or return to the avi files directly played by mplayer. To this end, you can use the following script program to automatically generate an index and then play back the video (where the $1 parameter is the avi video file name ):
#!/bin/bashmplayer -forceidx -saveidx "${1%avi}idx" "$1"
To play back a video that has been recorded and indexed, you can use the following script program (where $1 is the avi video file name ):
#!/bin/bashmplayer -loadidx "${1%avi}idx" "$1"
Now, the script program rtv. sh for playing and recording TV programs is complete. The following describes the script program stop_rtv.sh used to stop playing or recording. This is simple. It is nothing more than killing the corresponding process. The source code is as follows:
#!/bin/bash# Define a function for returning a process idfunction get_pid_by_name(){ local process_str echo "Searching process $1..." process_str=`ps aux | grep "$1" | tr --squeeze-repeats '[:blank:]+' '\t' | cut -f 2` if [ -n "$process_str" ]; then # The process for grep appears in the second field process_str=`echo $process_str | cut -s -d ' ' -f 1` if [ -n "$process_str" ]; then temp_pid=$process_str echo "The process id is $temp_pid!" else echo "The process $1 cannot be found, perfect!" fi else echo "The process $1 cannot be found, perfect!" fi}# Declare pid as integersdeclare -i temp_pid=-1 mplayer_pid=-1 mencoder_pid=-1 tee_pid=-1# Kill mencoder processget_pid_by_name mencodermencoder_pid=$temp_pidtemp_pid=-1if [ $(($mencoder_pid!=-1)) = 1 ]; then # The SIGINT has no effect on mencoder processes while SIGKILL will cause loss of /dev/video0 node kill -2 $mencoder_pid && echo "mencoder has been killed!"else echo "mencoder process does not exist!"fi# Kill tee processget_pid_by_name teetee_pid=$temp_pidtemp_pid=-1if [ $(($tee_pid!=-1)) = 1 ]; then kill -2 $tee_pid && echo "tee has been killed!"else echo "tee process does not exist!"fi# Kill mplayer process if not in nowatch modeif [ "$1" != "nowatch" ]; then get_pid_by_name mplayer mplayer_pid=$temp_pid temp_pid=-1 if [ $(($mplayer_pid!=-1)) = 1 ]; then # Note: mplayer is started by using sudo, therefore when killing it, sudo should also be used sudo -u orlando kill -2 $mplayer_pid && echo "mplayer has been killed!" else echo "mplayer process does not exist!" fifiecho "TV recording and playing have been stopped!"
With the rtv. sh and stop_rtv.sh scripts, combined with the at command, you can implement regular recording and program playback. For example:
$ At 20:00 todaywarning: commands will be executed using/bin/sh at> rtv watch I love invention at> <EOT> # Input Ctrl + Djob 21 at Wed Feb 5 20:00:00 2014 $ at todaywarning: commands will be executed using/bin/sh at> stop_rtv watchat> <EOT> # Input Ctrl + Djob 22 at Wed Feb 5 21:00:00 2014
Most of the TV programs broadcast at night will be replayed during the next day, so they can be recorded as planned at work. At the same time, programs that originally needed to stay up late at night can also be saved and watched the next day.
Another problem is that the TV card is inserted on the desktop, so you can only watch TV programs on this computer. So how do you watch TV while cooking in the kitchen? For example, why does one broadcast news at pm? Since you have an iPhone, it is not difficult to implement this function. First, run the rtv. sh Program (rtv. sh nowatch filename. avi) on the computer to upload the TV program directory to the file. Then, share the directory of the file to the Samba server. Finally, access the server with the OPlayer of the video player on the iPhone and play it online. The program is a little delayed, but it does not have much to do with it. Is the TV program on the iPhone:
This article permanently updates the link address: