Tuesday, December 22, 2009
Wednesday, August 5, 2009
Connecting IIS and Apache Tomcat
Apache tomcat is one of the most popular application servers on java platform. But when it comes to serving static web content in parallel with web applications, there should be a clear separation of job role as http servers like apache and IIS are better at serving static content.
This can be achieved by leaving static content to IIS and routing dynamic part to Tomcat. Thanks to apache , this is possible with JK connector which is an isapi filter, can be configured to work with IIS (checked with 5 and 6).
So,let's get started!

This can be achieved by leaving static content to IIS and routing dynamic part to Tomcat. Thanks to apache , this is possible with JK connector which is an isapi filter, can be configured to work with IIS (checked with 5 and 6).
So,let's get started!
- We need the connector extension installed first!
- Download and install the isapi extension (no hassel)
- By default the filter installs in C:\Program Files\Apache Software Foundation\Jakarta Isapi Redirector. All the configuration files (workers.properties.minimal and uriworkermap.properties) are found in the directory named conf.
- make sure tomcat has an ajp listener running on the same port as mentioned in workers.properties.minimal
- Look for the following lines in server.xml in <Tomcat base>/conf to make sure ajp is enabled
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> - add a couple of context forwarding (you can add /manager/*=wlb
just to check!)to tomcat in uriworkermap.properties - run tomcat
- Open the Internet Information Services(IIS) manager.
- Browse to <server name> -> Web Sites
- Right click on Default Web Site, then select New -> Virtual Directory.
Enter Jakarta for Alias name and select jakarta isapi redirector install dir/bin as directory. - For the permission page, select both Read and Execute check boxes.
Click Apply and close the dialog. - Right click on Default Web Site, and select properties.
In the popup dialog, select the ISAPI Filters tab.
Click Add. - Enter jakarta for Filter name, and jakarta isapi redirector install dir\bin\isapi_redirect.dll as executable.
Click Apply and close the dialog box. - Right click on Web Service Extensions and select Add a new Web service extension. Enter tomcat connector for Extension Name, and add jakarta isapi redirector install dir\bin\isapi_redirect.dll for required files field.
Select the Set extension status to Allowed check box and click OK to close the dialog box. - Stop and restart the Default Web Site by right clicking on it and select Stop and Start.
- If that doesn't work try restarting iis admin service from IIS in MMC

Wednesday, June 24, 2009
Making movies from image files using ffmpeg/mencoder Motivation
In my research, I often generate a sequence of images from either my
experiment or from a simulation that I want to put together into a movie.
Since I use linux, I wanted to do this using free software in linux, and I
wanted to be able to play the movie in linux. This webpage outlines what I've
learned about how to do this in linux using mencoder or ffmpeg to create high
quality files that are well compressed and the play well under all operating
systems.
The movies are going to be non-standard size (usually square, around 200x200
pixels for me), and have a non-standard frame rate: typcially, my movies may
only be 10 frames, so I don't want to run it at 30 fps.
The details
We want to encode to some kind of relatively portable movie format. ffmpeg and
mencoder both do this using the libavcodec library developed as part of
ffmpeg. The codec options from the mencoder man page include:
vcodec=
Employ the specified codec (default: mpeg4).
mjpeg
Motion JPEG
ljpeg
Lossless JPEG
h263
H.263
h263p
H.263+
mpeg4
MPEG-4 (DivX 4/5)
msmpeg4
DivX 3
msmpeg4v2
MS MPEG4v2
wmv1
Windows Media Video, version 1 (AKA WMV7)
wmv2
Windows Media Video, version 2 (AKA WMV8)
rv10
an old RealVideo codec
mpeg1video
MPEG-1 video
mpeg2video
MPEG-2 video
huffyuv
HuffYUV
asv1
ASUS Video v1
asv2
ASUS Video v2
ffv1
FFmpeg's lossless video codec
ffmpeg supports an even larger list of output codecs and container formats.
MPEG-1 and MPEG-2 streams are no good, since the frame rate is locked to 29.97
or 25 FPS. For an excellent overview of some of the common open-standard
compression methods, see this page.
(Note: "open" standard only means that the specifications aren't some
undocumented industry secret. It does not mean, however, that the formats are
not entrenched with patent issues, which mpeg4, and even mpeg1 and mpeg2,
most certainly are...You take what you can get, though.)
MJPEG would seem to be a good option, except that the files that we get seem
to be incompatible with windows media player for some reason (at least with
files encoded with mencoder). MJPEG supports arbitrary frame rates, but the
movies files could get large if you have a lot of frames since it doesn't use
temporal coding.
MPEG-4 is the best option. The mpeg4 stream can be stored in either in
the .avi or .mp4 (quicktime) container file: it can support high levels of
lossy compression to keep file sizes small and also supports arbitrary frame
rates. It is also translates much more easily to other platforms than wmv1 or
wmv2.
mencoder only supports avi file containers, which is a pity since the
quicktime widgets looks nicer, and the .mp4 container format has fewer issues
with compatibility (there are some fourcc issues with .avi: this container
file format issue is the only reason why the mpeg4 streams inside avi files
from DiVX, xvid, ..., codecs are incompatible! How stupid is that?)
Note also that mencoder (at least version 1.0pre6-3.3.3 does) will barf if we
use anything other than jpeg files as our input, so we should convert all our
images to jpeg's with 100% quality to avoid any quantization loss at this
stage:
$ for f in *ppm ; do convert -quality 100 $f `basename $f ppm`jpg; done
With mencoder, we can use the vbitrate option to set the degree of lossy
compression. Note that the default mpeg4 option will add a "DivX" logo to the
movie when playin in windows media player, so we prefer to use one of the
other mpeg4 encoders, such as msmpeg4 or msmpeg4v2. The commmand line I've
used is:
mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts
vcodec=msmpeg4v2:vbitrate=800
We can also use ffmpeg directly to encode the images files into a movie. If we
start with files name 001.jpg, 002.jpg, ..., we can use:
ffmpeg -r 10 -b 1800 -i %03d.jpg test1800.mp4
This works very well, and is nice because ffmpeg is included in debian! My
only complaint is that with ffmpeg is that you have to be careful that all
the files are named sequentially. For example, for a long time, I was missing
015.jpg, which caused it to encode only 15 frames. To get it to work, I had
to rename the files so that there were no gaps in the file numbers. The .mp4
files encoded this way will play fine with quicktime under windows, which I
peronally prefer over media player, and which will never show the stupid DiVX
logo, since it's doesn't use the braindead avi container. (see rant above...)
How do the file sizes compare?
Image files:
Initial ppms: 6.9 MB
Initial jpgs: 8.0 MB (100% quality)
Movies (10 frames per second): avi files are encoded using mspeg4v2, mp4 files
are done using the ffmpeg default (mpeg4).
1500 test1800.avi
900 test800.avi
528 test400.avi
1748 test1800.mp4
860 test800.mp4
504 test400.mp4
324 test200.mp4
264 test100.mp4
At 1800 kbits/sec, the quality is excellent, with no noticeable motion
artifacts. 800 is very good, but at 400, the motion artifacts become quite
noticeable.
Other useful stuff:
* Get a thumbnail from a movie using ffmpeg:
ffmpeg -i test.mp4 -f singlejpeg -t 0.001 test.jpg
* Movies can be embedded in pdf documents using latex! Use the style file
movie15.sty. This is really cool!
Check out this file for an example (latex source file is available
here). More info about how to do this is avilable from this website.
The movies will play fine under windows using acroread 7.0. Under linux,
if you install acrobat reader 7.0 for linux, you can save the embedded movies
to disk and play them form there.
experiment or from a simulation that I want to put together into a movie.
Since I use linux, I wanted to do this using free software in linux, and I
wanted to be able to play the movie in linux. This webpage outlines what I've
learned about how to do this in linux using mencoder or ffmpeg to create high
quality files that are well compressed and the play well under all operating
systems.
The movies are going to be non-standard size (usually square, around 200x200
pixels for me), and have a non-standard frame rate: typcially, my movies may
only be 10 frames, so I don't want to run it at 30 fps.
The details
We want to encode to some kind of relatively portable movie format. ffmpeg and
mencoder both do this using the libavcodec library developed as part of
ffmpeg. The codec options from the mencoder man page include:
vcodec=
Employ the specified codec (default: mpeg4).
mjpeg
Motion JPEG
ljpeg
Lossless JPEG
h263
H.263
h263p
H.263+
mpeg4
MPEG-4 (DivX 4/5)
msmpeg4
DivX 3
msmpeg4v2
MS MPEG4v2
wmv1
Windows Media Video, version 1 (AKA WMV7)
wmv2
Windows Media Video, version 2 (AKA WMV8)
rv10
an old RealVideo codec
mpeg1video
MPEG-1 video
mpeg2video
MPEG-2 video
huffyuv
HuffYUV
asv1
ASUS Video v1
asv2
ASUS Video v2
ffv1
FFmpeg's lossless video codec
ffmpeg supports an even larger list of output codecs and container formats.
MPEG-1 and MPEG-2 streams are no good, since the frame rate is locked to 29.97
or 25 FPS. For an excellent overview of some of the common open-standard
compression methods, see this page.
(Note: "open" standard only means that the specifications aren't some
undocumented industry secret. It does not mean, however, that the formats are
not entrenched with patent issues, which mpeg4, and even mpeg1 and mpeg2,
most certainly are...You take what you can get, though.)
MJPEG would seem to be a good option, except that the files that we get seem
to be incompatible with windows media player for some reason (at least with
files encoded with mencoder). MJPEG supports arbitrary frame rates, but the
movies files could get large if you have a lot of frames since it doesn't use
temporal coding.
MPEG-4 is the best option. The mpeg4 stream can be stored in either in
the .avi or .mp4 (quicktime) container file: it can support high levels of
lossy compression to keep file sizes small and also supports arbitrary frame
rates. It is also translates much more easily to other platforms than wmv1 or
wmv2.
mencoder only supports avi file containers, which is a pity since the
quicktime widgets looks nicer, and the .mp4 container format has fewer issues
with compatibility (there are some fourcc issues with .avi: this container
file format issue is the only reason why the mpeg4 streams inside avi files
from DiVX, xvid, ..., codecs are incompatible! How stupid is that?)
Note also that mencoder (at least version 1.0pre6-3.3.3 does) will barf if we
use anything other than jpeg files as our input, so we should convert all our
images to jpeg's with 100% quality to avoid any quantization loss at this
stage:
$ for f in *ppm ; do convert -quality 100 $f `basename $f ppm`jpg; done
With mencoder, we can use the vbitrate option to set the degree of lossy
compression. Note that the default mpeg4 option will add a "DivX" logo to the
movie when playin in windows media player, so we prefer to use one of the
other mpeg4 encoders, such as msmpeg4 or msmpeg4v2. The commmand line I've
used is:
mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts
vcodec=msmpeg4v2:vbitrate=800
We can also use ffmpeg directly to encode the images files into a movie. If we
start with files name 001.jpg, 002.jpg, ..., we can use:
ffmpeg -r 10 -b 1800 -i %03d.jpg test1800.mp4
This works very well, and is nice because ffmpeg is included in debian! My
only complaint is that with ffmpeg is that you have to be careful that all
the files are named sequentially. For example, for a long time, I was missing
015.jpg, which caused it to encode only 15 frames. To get it to work, I had
to rename the files so that there were no gaps in the file numbers. The .mp4
files encoded this way will play fine with quicktime under windows, which I
peronally prefer over media player, and which will never show the stupid DiVX
logo, since it's doesn't use the braindead avi container. (see rant above...)
How do the file sizes compare?
Image files:
Initial ppms: 6.9 MB
Initial jpgs: 8.0 MB (100% quality)
Movies (10 frames per second): avi files are encoded using mspeg4v2, mp4 files
are done using the ffmpeg default (mpeg4).
1500 test1800.avi
900 test800.avi
528 test400.avi
1748 test1800.mp4
860 test800.mp4
504 test400.mp4
324 test200.mp4
264 test100.mp4
At 1800 kbits/sec, the quality is excellent, with no noticeable motion
artifacts. 800 is very good, but at 400, the motion artifacts become quite
noticeable.
Other useful stuff:
* Get a thumbnail from a movie using ffmpeg:
ffmpeg -i test.mp4 -f singlejpeg -t 0.001 test.jpg
* Movies can be embedded in pdf documents using latex! Use the style file
movie15.sty. This is really cool!
Check out this file for an example (latex source file is available
here). More info about how to do this is avilable from this website.
The movies will play fine under windows using acroread 7.0. Under linux,
if you install acrobat reader 7.0 for linux, you can save the embedded movies
to disk and play them form there.
Linux Force Unmount Script
create a file in /usr/bin after chmod +x from root
then copy the following script and save !
#!/bin/bash
# TODO: accept either dir or device on command line (like umount does)
# ie: /mnt/tmp or /dev/hda6
# TODO: accept relative dirs
# ie: cd /mnt; fumount tmp
declare -rx SCRIPT=${0##*/}
declare -rx VERSION=001
if [ `whoami` != "root" ]; then
echo "You must run this as root"
exit 1
fi
# display script usage, then exit
function usage {
printf "usage: $SCRIPT [-i] [-v] dir\n" >&2
printf " -i : interactive mode\n" >&2
printf " -v : verbose\n" >&2
success=1 # don't print failure message
exit 1
}
# print verbose/debug information
function debug {
if [ -n "$verbose" ]; then
printf "$1"
fi
}
# umount was a success
function success {
success=1
debug "$mntpoint unmounted\n"
exit 0
}
function on_exit {
if [ -z "$success" ]; then
printf "unmount failed\n" >&2
fi
}
trap on_exit EXIT
# parse the arguments
while [ -n "$1" ]; do
case $1 in
-i)
interactive=1
;;
-v)
verbose=1
;;
-*)
usage
;;
*)
if [ -z "$mntpoint" ]; then
mntpoint=$1
else
usage
fi
;;
esac
shift
done
if [ -z "$mntpoint" ]; then
usage
fi
# strip trailing slash from mntpoint
# surely there must be a better way to do this...
while [ "`echo "$mntpoint" |grep '/$'`" ]; do
mntpoint=${mntpoint%/}
done
# attempt a regular umount
tryumount=`umount $mntpoint 2>&1`
ret=$?
if [ "`echo $tryumount |grep 'not mounted'`" ]; then
printf "%s is not mounted\n" "$mntpoint" >&2
if [ -e "$mntpoint" ]; then
printf "You must provide the full path (ie: /mnt/tmp)\n" >&2
fi
exit 1
fi
if [ "`echo $tryumount |grep 'not found'`" ]; then
printf "%s not fount\n" "$mntpoint" >&2
exit 1
fi
# did the umount succeed?
if [ $ret -eq 0 ]; then
success
else
# if the filesystem is busy, kill all processes accessing it
if [ "`echo $tryumount |grep 'busy'`" ]; then
debug "busy... killing all processes accessing the filesystem\n"
if [ "$interactive" ]; then
fuser -ki $mntpoint
else
fuser -k $mntpoint &> /dev/null
fi
else
printf "%s failed... umount returned %d\n" "$SCRIPT" "$ret" >&2
exit 1
fi
fi
# try to umount again
tryumount=`umount $mntpoint 2>&1`
ret=$?
if [ $ret -eq 0 ]; then
success
else
if [ "`echo $tryumount | grep 'busy'`" ]; then
# get the name of the device that is mounted
exec 6<&0 # save stdin... better way to do this?
exec < /proc/mounts
while read line; do
mnt=`echo $line |awk '{print $2}'`
if [ "$mnt" = "$mntpoint" ]; then
device=`echo $line |awk '{print $1}'`
break
fi
done
exec 0<&6 6<&- # restore stdin
# our first attempt didn't work, do lazy umount to make it easier
debug "still busy, doing lazy umount\n"
if [ "$interactive" ]; then
printf "Do a lazy unmount? (y/N)\n"
read yn
if [ "$yn" != "y" ]; then
exit 1
fi
fi
umount -l $mntpoint
# keep trying to kill processes accessing the device. don't exit until
# we succeed
while [ -n "$device" -a -e "$device" ]; do
debug "attempting to kill all processes accessing $device\n"
if [ "$interactive" ]; then
fuser -kmi $device
else
fuser -km $device &> /dev/null
fi
if [ -z "`fuser -m $device`" ]; then
success
fi
done
printf "Lazy unmount succeeded, but I was unable to find the\n"
printf "device the filesystem was mounted on. There may still be\n"
printf "processes accessing the device.\n"
exit 0
else
printf "%s failed... umount returned %d\n" "$SCRIPT" "$ret" >&2
exit 1
fi
fi
then copy the following script and save !
#!/bin/bash
# TODO: accept either dir or device on command line (like umount does)
# ie: /mnt/tmp or /dev/hda6
# TODO: accept relative dirs
# ie: cd /mnt; fumount tmp
declare -rx SCRIPT=${0##*/}
declare -rx VERSION=001
if [ `whoami` != "root" ]; then
echo "You must run this as root"
exit 1
fi
# display script usage, then exit
function usage {
printf "usage: $SCRIPT [-i] [-v] dir\n" >&2
printf " -i : interactive mode\n" >&2
printf " -v : verbose\n" >&2
success=1 # don't print failure message
exit 1
}
# print verbose/debug information
function debug {
if [ -n "$verbose" ]; then
printf "$1"
fi
}
# umount was a success
function success {
success=1
debug "$mntpoint unmounted\n"
exit 0
}
function on_exit {
if [ -z "$success" ]; then
printf "unmount failed\n" >&2
fi
}
trap on_exit EXIT
# parse the arguments
while [ -n "$1" ]; do
case $1 in
-i)
interactive=1
;;
-v)
verbose=1
;;
-*)
usage
;;
*)
if [ -z "$mntpoint" ]; then
mntpoint=$1
else
usage
fi
;;
esac
shift
done
if [ -z "$mntpoint" ]; then
usage
fi
# strip trailing slash from mntpoint
# surely there must be a better way to do this...
while [ "`echo "$mntpoint" |grep '/$'`" ]; do
mntpoint=${mntpoint%/}
done
# attempt a regular umount
tryumount=`umount $mntpoint 2>&1`
ret=$?
if [ "`echo $tryumount |grep 'not mounted'`" ]; then
printf "%s is not mounted\n" "$mntpoint" >&2
if [ -e "$mntpoint" ]; then
printf "You must provide the full path (ie: /mnt/tmp)\n" >&2
fi
exit 1
fi
if [ "`echo $tryumount |grep 'not found'`" ]; then
printf "%s not fount\n" "$mntpoint" >&2
exit 1
fi
# did the umount succeed?
if [ $ret -eq 0 ]; then
success
else
# if the filesystem is busy, kill all processes accessing it
if [ "`echo $tryumount |grep 'busy'`" ]; then
debug "busy... killing all processes accessing the filesystem\n"
if [ "$interactive" ]; then
fuser -ki $mntpoint
else
fuser -k $mntpoint &> /dev/null
fi
else
printf "%s failed... umount returned %d\n" "$SCRIPT" "$ret" >&2
exit 1
fi
fi
# try to umount again
tryumount=`umount $mntpoint 2>&1`
ret=$?
if [ $ret -eq 0 ]; then
success
else
if [ "`echo $tryumount | grep 'busy'`" ]; then
# get the name of the device that is mounted
exec 6<&0 # save stdin... better way to do this?
exec < /proc/mounts
while read line; do
mnt=`echo $line |awk '{print $2}'`
if [ "$mnt" = "$mntpoint" ]; then
device=`echo $line |awk '{print $1}'`
break
fi
done
exec 0<&6 6<&- # restore stdin
# our first attempt didn't work, do lazy umount to make it easier
debug "still busy, doing lazy umount\n"
if [ "$interactive" ]; then
printf "Do a lazy unmount? (y/N)\n"
read yn
if [ "$yn" != "y" ]; then
exit 1
fi
fi
umount -l $mntpoint
# keep trying to kill processes accessing the device. don't exit until
# we succeed
while [ -n "$device" -a -e "$device" ]; do
debug "attempting to kill all processes accessing $device\n"
if [ "$interactive" ]; then
fuser -kmi $device
else
fuser -km $device &> /dev/null
fi
if [ -z "`fuser -m $device`" ]; then
success
fi
done
printf "Lazy unmount succeeded, but I was unable to find the\n"
printf "device the filesystem was mounted on. There may still be\n"
printf "processes accessing the device.\n"
exit 0
else
printf "%s failed... umount returned %d\n" "$SCRIPT" "$ret" >&2
exit 1
fi
fi
How to Monitor Remote JVM
/*
* JVMRuntimeClient.java
*
* Created on March 9, 2007, 2:44 PM
*
* Copyright (c) Sun Microsystems, 2007 - All rights reserved.
*/
package jvmruntime;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.util.logging.Logger;
import javax.management.remote.JMXServiceURL;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.List;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
/**
* Class JVMRuntimeClient - Shows how to programmatically connect to
* a running VM and interact with its RuntimeMXBean.
*
* @author Sun Microsystems, 2007 - All rights reserved.
*/
public class JVMRuntimeClient {
/**
* A logger for this class.
**/
private static final Logger LOG =
Logger.getLogger(JVMRuntimeClient.class.getName());
/** Creates a new instance of Main */
public JVMRuntimeClient() {
}
/**
* A helper class to analyze the command line and create a JMXServiceURL.
* Allows to pass a JMXServiceURL, a host and port, or a VM PID.
**/
public static class ConnectionArgs {
private static final String CONNECTOR_ADDRESS =
"com.sun.management.jmxremote.localConnectorAddress";
public final JMXServiceURL jmxURL;
final public String SYNTAX = "JVMRuntimeClient -url <jmx-url> " +
"| -port <port-number> [-host <host-or-ip] " +
"| -pid <pid> | -help";
public ConnectionArgs(String[] args) {
jmxURL = parseArgs(args);
}
public final JMXServiceURL getJMXServiceURL() {
return jmxURL;
}
private JMXServiceURL parseArgs(String[] args) {
String host = null;
int port = 0;
String pid = null;
JMXServiceURL serviceURL = null;
for (int i=0;i<args.length;i++) {
if (args[i].startsWith("-url")) {
// The '-url' option will let you specify a JMXServiceURL
// on the command line. This is an URL that begins with
// service:jmx:<protocol>
//
if (host != null)
throwSyntaxError(
"-url and -host are mutually exclusive");
if (pid != null)
throwSyntaxError(
"-pid and -url are mutually exclusive");
if (port > 0)
throwSyntaxError(
"-port and -url are mutually exclusive");
if (++i >= args.length)
throwSyntaxError(
"missing JMXServiceURL after -url");
try {
serviceURL = new JMXServiceURL(args[i]);
} catch (Exception x) {
throwSyntaxError("bad JMXServiceURL after -url: " + x);
}
continue;
} else if (args[i].startsWith("-host")) {
// The '-host' and '-port' options will let you specify a host
// and port, and from that will construct the JMXServiceURL of
// the default RMI connector, that is:
// service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi"
//
if (serviceURL != null)
throwSyntaxError("-url and -host are mutually exclusive");
if (pid != null)
throwSyntaxError("-pid and -host are mutually exclusive");
if (++i >= args.length)
throwSyntaxError("missing host after -host");
try {
InetAddress.getByName(args[i]);
host = args[i];
} catch (Exception x) {
throwSyntaxError("bad host after -url: " + x);
}
} else if (args[i].startsWith("-port")) {
// The '-host' and '-port' options will let you specify a host
// and port, and from that will construct the JMXServiceURL of
// the default RMI connector, that is:
// service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi"
//
if (serviceURL != null)
throwSyntaxError("-url and -port are mutually exclusive");
if (pid != null)
throwSyntaxError("-pid and -port are mutually exclusive");
if (++i >= args.length)
throwSyntaxError("missing port number after -port");
try {
port = Integer.parseInt(args[i]);
if (port <= 0)
throwSyntaxError("bad port number after -port: " +
"must be positive");
} catch (Exception x) {
throwSyntaxError("bad port number after -port: " + x);
}
} else if (args[i].startsWith("-pid")) {
// The '-pid' and option will let you specify the PID of the
// target VM you want to connect to. It will then use the
// attach API to dynamically launch the JMX agent in the target
// VM (if needed) and to find out the JMXServiceURL of the
// the default JMX Connector in that VM.
//
if (serviceURL != null)
throwSyntaxError("-url and -pid are mutually exclusive");
if (port > 0)
throwSyntaxError("-port and -pid are mutually exclusive");
if (++i >= args.length)
throwSyntaxError("missing pid after -pid");
try {
pid = args[i];
} catch (Exception x) {
throwSyntaxError("bad pid after -pid: " + x);
}
} else if (args[i].startsWith("-help")) {
final List<String> vmlist = new ArrayList();
for (VirtualMachineDescriptor vd : VirtualMachine.list()) {
vmlist.add(vd.id());
}
System.err.println(SYNTAX);
System.err.println("Running JVMs are: "+vmlist);
throw new IllegalArgumentException(SYNTAX);
} else {
throwSyntaxError("Unknown argument: "+args[i]);
}
}
// A JMXServiceURL was given on the command line, just use this.
//
if (serviceURL != null)
return serviceURL;
// A -host -port info was given on the command line.
// Construct the default RMI JMXServiceURL from this.
//
if (port > 0) {
if (host == null)
host = "localhost";
try {
return new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+
host+":"+port+"/jmxrmi");
} catch (Exception x) {
throwSyntaxError("Bad host or port number: "+x);
}
}
// A PID was given on the command line.
// Use the attach API to find the target's connector address, and
// start it if needed.
//
if (pid != null) {
try {
return getURLForPid(pid);
} catch (Exception x) {
throwSyntaxError("cannot attach to target vm "+pid+": "+x);
}
}
final List<String> vmlist = new ArrayList();
for (VirtualMachineDescriptor vd : VirtualMachine.list()) {
vmlist.add(vd.id());
}
throwSyntaxError("missing argument: "+ "-port | -url | -pid | -list"
+"\n\tRunning VMs are: "+vmlist);
// Unreachable.
return null;
}
private void throwSyntaxError(String msg) {
System.err.println(msg);
System.err.println(SYNTAX);
throw new IllegalArgumentException(msg);
}
private JMXServiceURL getURLForPid(String pid) throws Exception {
// attach to the target application
final VirtualMachine vm = VirtualMachine.attach(pid);
// get the connector address
String connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
// no connector address, so we start the JMX agent
if (connectorAddress == null) {
String agent = vm.getSystemProperties().getProperty("java.home") +
File.separator + "lib" + File.separator + "management-agent.jar";
vm.loadAgent(agent);
// agent is started, get the connector address
connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
assert connectorAddress != null;
}
return new JMXServiceURL(connectorAddress);
}
}
/**
* @param args the command line arguments:
* must be -url <jmx-url>,
* or -port <port-number> [-host <host-or-ip],
* or -pid <pid>,
* or -help
*/
public static void main(String[] args) throws Exception {
// Parse arguments.
final ConnectionArgs cArgs = new ConnectionArgs(args);
// Get target's URL
final JMXServiceURL target = cArgs.getJMXServiceURL();
// Connect to target (assuming no security)
final JMXConnector connector = JMXConnectorFactory.connect(target);
// Get an MBeanServerConnection on the remote VM.
final MBeanServerConnection remote =
connector.getMBeanServerConnection();
final RuntimeMXBean remoteRuntime =
ManagementFactory.newPlatformMXBeanProxy(
remote,
ManagementFactory.RUNTIME_MXBEAN_NAME,
RuntimeMXBean.class);
System.out.println("Target VM is: "+remoteRuntime.getName());
System.out.println("Started since: "+remoteRuntime.getUptime());
System.out.println("With Classpath: "+remoteRuntime.getClassPath());
System.out.println("And args: "+remoteRuntime.getInputArguments());
connector.close();
}
}
* JVMRuntimeClient.java
*
* Created on March 9, 2007, 2:44 PM
*
* Copyright (c) Sun Microsystems, 2007 - All rights reserved.
*/
package jvmruntime;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.util.logging.Logger;
import javax.management.remote.JMXServiceURL;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.List;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
/**
* Class JVMRuntimeClient - Shows how to programmatically connect to
* a running VM and interact with its RuntimeMXBean.
*
* @author Sun Microsystems, 2007 - All rights reserved.
*/
public class JVMRuntimeClient {
/**
* A logger for this class.
**/
private static final Logger LOG =
Logger.getLogger(JVMRuntimeClient.class.getName());
/** Creates a new instance of Main */
public JVMRuntimeClient() {
}
/**
* A helper class to analyze the command line and create a JMXServiceURL.
* Allows to pass a JMXServiceURL, a host and port, or a VM PID.
**/
public static class ConnectionArgs {
private static final String CONNECTOR_ADDRESS =
"com.sun.management.jmxremote.localConnectorAddress";
public final JMXServiceURL jmxURL;
final public String SYNTAX = "JVMRuntimeClient -url <jmx-url> " +
"| -port <port-number> [-host <host-or-ip] " +
"| -pid <pid> | -help";
public ConnectionArgs(String[] args) {
jmxURL = parseArgs(args);
}
public final JMXServiceURL getJMXServiceURL() {
return jmxURL;
}
private JMXServiceURL parseArgs(String[] args) {
String host = null;
int port = 0;
String pid = null;
JMXServiceURL serviceURL = null;
for (int i=0;i<args.length;i++) {
if (args[i].startsWith("-url")) {
// The '-url' option will let you specify a JMXServiceURL
// on the command line. This is an URL that begins with
// service:jmx:<protocol>
//
if (host != null)
throwSyntaxError(
"-url and -host are mutually exclusive");
if (pid != null)
throwSyntaxError(
"-pid and -url are mutually exclusive");
if (port > 0)
throwSyntaxError(
"-port and -url are mutually exclusive");
if (++i >= args.length)
throwSyntaxError(
"missing JMXServiceURL after -url");
try {
serviceURL = new JMXServiceURL(args[i]);
} catch (Exception x) {
throwSyntaxError("bad JMXServiceURL after -url: " + x);
}
continue;
} else if (args[i].startsWith("-host")) {
// The '-host' and '-port' options will let you specify a host
// and port, and from that will construct the JMXServiceURL of
// the default RMI connector, that is:
// service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi"
//
if (serviceURL != null)
throwSyntaxError("-url and -host are mutually exclusive");
if (pid != null)
throwSyntaxError("-pid and -host are mutually exclusive");
if (++i >= args.length)
throwSyntaxError("missing host after -host");
try {
InetAddress.getByName(args[i]);
host = args[i];
} catch (Exception x) {
throwSyntaxError("bad host after -url: " + x);
}
} else if (args[i].startsWith("-port")) {
// The '-host' and '-port' options will let you specify a host
// and port, and from that will construct the JMXServiceURL of
// the default RMI connector, that is:
// service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi"
//
if (serviceURL != null)
throwSyntaxError("-url and -port are mutually exclusive");
if (pid != null)
throwSyntaxError("-pid and -port are mutually exclusive");
if (++i >= args.length)
throwSyntaxError("missing port number after -port");
try {
port = Integer.parseInt(args[i]);
if (port <= 0)
throwSyntaxError("bad port number after -port: " +
"must be positive");
} catch (Exception x) {
throwSyntaxError("bad port number after -port: " + x);
}
} else if (args[i].startsWith("-pid")) {
// The '-pid' and option will let you specify the PID of the
// target VM you want to connect to. It will then use the
// attach API to dynamically launch the JMX agent in the target
// VM (if needed) and to find out the JMXServiceURL of the
// the default JMX Connector in that VM.
//
if (serviceURL != null)
throwSyntaxError("-url and -pid are mutually exclusive");
if (port > 0)
throwSyntaxError("-port and -pid are mutually exclusive");
if (++i >= args.length)
throwSyntaxError("missing pid after -pid");
try {
pid = args[i];
} catch (Exception x) {
throwSyntaxError("bad pid after -pid: " + x);
}
} else if (args[i].startsWith("-help")) {
final List<String> vmlist = new ArrayList();
for (VirtualMachineDescriptor vd : VirtualMachine.list()) {
vmlist.add(vd.id());
}
System.err.println(SYNTAX);
System.err.println("Running JVMs are: "+vmlist);
throw new IllegalArgumentException(SYNTAX);
} else {
throwSyntaxError("Unknown argument: "+args[i]);
}
}
// A JMXServiceURL was given on the command line, just use this.
//
if (serviceURL != null)
return serviceURL;
// A -host -port info was given on the command line.
// Construct the default RMI JMXServiceURL from this.
//
if (port > 0) {
if (host == null)
host = "localhost";
try {
return new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+
host+":"+port+"/jmxrmi");
} catch (Exception x) {
throwSyntaxError("Bad host or port number: "+x);
}
}
// A PID was given on the command line.
// Use the attach API to find the target's connector address, and
// start it if needed.
//
if (pid != null) {
try {
return getURLForPid(pid);
} catch (Exception x) {
throwSyntaxError("cannot attach to target vm "+pid+": "+x);
}
}
final List<String> vmlist = new ArrayList();
for (VirtualMachineDescriptor vd : VirtualMachine.list()) {
vmlist.add(vd.id());
}
throwSyntaxError("missing argument: "+ "-port | -url | -pid | -list"
+"\n\tRunning VMs are: "+vmlist);
// Unreachable.
return null;
}
private void throwSyntaxError(String msg) {
System.err.println(msg);
System.err.println(SYNTAX);
throw new IllegalArgumentException(msg);
}
private JMXServiceURL getURLForPid(String pid) throws Exception {
// attach to the target application
final VirtualMachine vm = VirtualMachine.attach(pid);
// get the connector address
String connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
// no connector address, so we start the JMX agent
if (connectorAddress == null) {
String agent = vm.getSystemProperties().getProperty("java.home") +
File.separator + "lib" + File.separator + "management-agent.jar";
vm.loadAgent(agent);
// agent is started, get the connector address
connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
assert connectorAddress != null;
}
return new JMXServiceURL(connectorAddress);
}
}
/**
* @param args the command line arguments:
* must be -url <jmx-url>,
* or -port <port-number> [-host <host-or-ip],
* or -pid <pid>,
* or -help
*/
public static void main(String[] args) throws Exception {
// Parse arguments.
final ConnectionArgs cArgs = new ConnectionArgs(args);
// Get target's URL
final JMXServiceURL target = cArgs.getJMXServiceURL();
// Connect to target (assuming no security)
final JMXConnector connector = JMXConnectorFactory.connect(target);
// Get an MBeanServerConnection on the remote VM.
final MBeanServerConnection remote =
connector.getMBeanServerConnection();
final RuntimeMXBean remoteRuntime =
ManagementFactory.newPlatformMXBeanProxy(
remote,
ManagementFactory.RUNTIME_MXBEAN_NAME,
RuntimeMXBean.class);
System.out.println("Target VM is: "+remoteRuntime.getName());
System.out.println("Started since: "+remoteRuntime.getUptime());
System.out.println("With Classpath: "+remoteRuntime.getClassPath());
System.out.println("And args: "+remoteRuntime.getInputArguments());
connector.close();
}
}
Monday, February 11, 2008
Free Record your favourite TV programs and Movies. The Open Source Linux Way!
So, We have IPL cricket series coming up
and you can't find a way to watch them because you
work in shift? Or, you have a computer at home and
you are looking for the most cost effective way of
recording your favourite TV shows
(be it NBA Baseball or race for NASCAR or clowning at WWE)
You have come to the right place my friend!
If you don't have much time you can jump to the "Let's get started"
section.
Long ago there was a time when I spent lonely hours tweaking
and turning all the stones to get a perfect recording from a windows
based system. I was using the software that came with my tv card.
My TV tuner is an old one from Pinnacle. It has one of those nice
saa7134 Philips chips and records entirely in software.
Usual VCD recording was okay, but the problem started
when I went for a DVD quality recording. The software based
encoder was a CPU hog. It ate up almost 75-80 % of my CPU
clogging down my system. And when I thought about MPEG4
quality, guess what, sometimes the program started to freeze.
Even I lowered the resolution of the video, still audio video
sync was a major problem. I couldn't even encode audio part of
the signal as mp3(using LAME). It just wouldn't record in any
other format except wav. And windows is notorious for its
clumsy driver model and slow framerate. There are so many
layers of abstraction in Windows directshow that when a problem
occurs (like with Smart Tee filter outputs extreme low resolution
video while recording) it is just nearly impossible for a simple
user like me to understand the cause and troubleshoot.
In those days Linux still had 2.4x kernel and did not
support by TV card out of the box. It was a painful process
of recompiling the kernel with a custom hack (patch) to get
my card working properly with any distribution. But then
came the Next Generation Kernel 2.6x
This was a major leap forward in hardware support
(we wouldn't dig much deep into it as it's way out of scope).
So I downloaded the most talked about distribution of the time
SuSe 10.2 32bit x86 DVD distribution. Man, this thing rocks!
Right form the installation with those fancy GUI installer,
to the configuration with Yast which is virtually THE tool
for a system wide common configuration I didn't feel the pain
of configuring a tidy linux box. And here is the best part, my TV
card worked out of the box.
The next thing was to set up a recording station to record
my favourite show. The best thing about this is, it's all free and
legal, if you do not copy copywrited material(mostly movies).
This is where we will begin describing the process of configuring
your linux box (with a supported TV card) as a TIVO like
PVR. Fasten your seat belts!!
Let's get started:
Things that we will need are the following.
1: mplayer with mencoder (you can download source and compile it)
or you may install packed binary released for your distribution.
2: open up the terminal and type
ls /proc/acpi
and hit enter. See if you can find an item in the list that says
alarm
if you do, we will possibly be able to poweron and poweroff
the system for automatically when we need to record something.
3: Last but not the least, you need a lot of freespace as video recording
is a space consuming task
First install the mplayer and mencoder as root.
now, if you have only one TV card in your computer
you will find it under /dev/video0 configured as
a V4L device. We can write the following
command to check if the TV card is working.
mplayer tv:// -tv driver=v4l2:input=0:norm=pal:width=640:height=480:device=/dev/video0:\
freq=775.25:adevice=/dev/dsp1:forceaudio:audiorate=32000
If there is no sound check the followings.
1:Check your loopback audio cable from the TV card sound out, see if it is connected to
the Line In of the sound card.
2: From alsamixer or kmix or any other sound mixer unmute the line in and increase
the sound.
you can use "h" and "k" to browse the other channels.
Now we will record a test video.
Now become root or sudo and perform the following steps.
Copy this script to a file named vcrui.sh
#!/bin/bash
ROOT_UID=0
NARGS=1
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "You must be root to record a program"
exit $E_NOTROOT
fi
if [ $# -ge "$NARGS" ]
then
echo "Feature Not Implemented"
exit $E_NO_ARGS_SUPPORTED
fi
echo "Enter channel number::"
read xnumber
echo "Enter Program Name::"
read xname
echo "Enter duration in Seconds::"
read xduration
exec ./vr.sh $xnumber $xduration $xname /LinuxBackup/TV/
# EOF
And create another script file named vr.sh
with the following codes
#!/bin/bash
if [ $# -le 2 ]
then
echo "Usage: $0 channel seconds title optional->>path"
exit
fi
rmmod saa7134
modprobe saa7134
FIL=$(date +%F_%H%M)\_$1$3
WIDTH=352
HEIGHT=264
MENCODER=/usr/local/bin/mencoder
AUDIO="-oac mp3lame -lameopts cbr:br=128:mode=3"
VIDEO="-ovc lavc -lavcopts vcodec=mpeg4:mbd=2:vbitrate=700:aspect=4/3"
DSP="adevice=/dev/dsp"
TV=" -tv driver=v4l2:width=$WIDTH:height=$HEIGHT:outfmt=yuy2:device=/dev/video0:input=0:norm=PAL:chanlist=europe-west:channel=$1:$DSP"
$MENCODER tv:// $TV $VIDEO $AUDIO -endpos $2 -ffourcc divx -o "$4$FIL.avi"
sync
exit
Now, change the file type of both of the script files to executable.
chmod +x *.sh
now create the following folder path if it does not exist
/LinuxBackup/TV/
the command is
mkdir -p /LinuxBackup/TV/vcr
now open up the recording wizard with the following command
./vcrui.sh
and follow the wizard and record a 2 minutes video.
play the video with mlayer.
Now we will setup an automatic recording with the tool
NU-Tcron
Go to the following website http://supratim.nonlogic.org and download it
once downloaded, extract and compile with the command as root.
./configure;make;make install;
once installed start the service if it already has not started.
(check the instructions inside the source archive for details on hibernate hooks
. This is very important, otherwise it wouln't work properly)
Now create the following recording script (it applies for suse)(check your
distro for hibernate support and command)
file vcr.sh
#!/bin/bash
if [ $# -le 2 ]
then
echo "Usage: $0 channel seconds title optional->>path"
exit
fi
rmmod saa7134
modprobe saa7134
FIL=$(date +%F_%H%M)\_$1$3
WIDTH=352
HEIGHT=264
MENCODER=/usr/local/bin/mencoder
AUDIO="-oac mp3lame -lameopts cbr:br=128:mode=3"
VIDEO="-ovc lavc -lavcopts vcodec=mpeg4:mbd=2:vbitrate=700:aspect=4/3"
DSP="adevice=/dev/dsp"
TV=" -tv driver=v4l2:width=$WIDTH:height=$HEIGHT:outfmt=yuy2:device=/dev/video0:input=0:norm=PAL:chanlist=europe-west:channel=$1:$DSP"
$MENCODER tv:// $TV $VIDEO $AUDIO -endpos $2 -ffourcc divx -o "$4$FIL.avi"
sync
pm-hibernate
Once you create this and change permission to executable, go back to the terminal
and type
tcrontab -e
and type in a command like the following
15 7 30 3 * /bin/bash /LinuxBackup/vcr/vcr.sh 33 8100 Threshold /LinuxBackup/TV/
a b c d e ..................... f .............................. g h i ....... j ...................
where ....
a is military hour (3 PM)
b is minute
c is day of the month
d is month of the year
e we don't need to mention so we put *
f bash command for execution path of the vcr script
(make sure you create vcr folder and copy vcr.sh into it)
g channel number
h record how many seconds
i a name of the program
j archival path of the video ( a partition with a lot of free space)
with this settings a full length 2 hour movie would take
almost 700mb (a CD)
If you have set up NU-Tcron properly, you can now hibernate
(Please don't turn off the power supply)
your linux box. It will automatically wake up the movie and
go back to hibernation.
So, never miss a single movie on TV. I also have some info
on how to setup the whole thing with automatically downloaded
EPG from the internet and record your favourite movies on the
basis of IMDB rating. But that's another story. Check back to my
website and I will post that also, soon( If I find some time).
and you can't find a way to watch them because you
work in shift? Or, you have a computer at home and
you are looking for the most cost effective way of
recording your favourite TV shows
(be it NBA Baseball or race for NASCAR or clowning at WWE)
You have come to the right place my friend!
If you don't have much time you can jump to the "Let's get started"
section.
Long ago there was a time when I spent lonely hours tweaking
and turning all the stones to get a perfect recording from a windows
based system. I was using the software that came with my tv card.
My TV tuner is an old one from Pinnacle. It has one of those nice
saa7134 Philips chips and records entirely in software.
Usual VCD recording was okay, but the problem started
when I went for a DVD quality recording. The software based
encoder was a CPU hog. It ate up almost 75-80 % of my CPU
clogging down my system. And when I thought about MPEG4
quality, guess what, sometimes the program started to freeze.
Even I lowered the resolution of the video, still audio video
sync was a major problem. I couldn't even encode audio part of
the signal as mp3(using LAME). It just wouldn't record in any
other format except wav. And windows is notorious for its
clumsy driver model and slow framerate. There are so many
layers of abstraction in Windows directshow that when a problem
occurs (like with Smart Tee filter outputs extreme low resolution
video while recording) it is just nearly impossible for a simple
user like me to understand the cause and troubleshoot.
In those days Linux still had 2.4x kernel and did not
support by TV card out of the box. It was a painful process
of recompiling the kernel with a custom hack (patch) to get
my card working properly with any distribution. But then
came the Next Generation Kernel 2.6x
This was a major leap forward in hardware support
(we wouldn't dig much deep into it as it's way out of scope).
So I downloaded the most talked about distribution of the time
SuSe 10.2 32bit x86 DVD distribution. Man, this thing rocks!
Right form the installation with those fancy GUI installer,
to the configuration with Yast which is virtually THE tool
for a system wide common configuration I didn't feel the pain
of configuring a tidy linux box. And here is the best part, my TV
card worked out of the box.
The next thing was to set up a recording station to record
my favourite show. The best thing about this is, it's all free and
legal, if you do not copy copywrited material(mostly movies).
This is where we will begin describing the process of configuring
your linux box (with a supported TV card) as a TIVO like
PVR. Fasten your seat belts!!
Let's get started:
Things that we will need are the following.
1: mplayer with mencoder (you can download source and compile it)
or you may install packed binary released for your distribution.
2: open up the terminal and type
ls /proc/acpi
and hit enter. See if you can find an item in the list that says
alarm
if you do, we will possibly be able to poweron and poweroff
the system for automatically when we need to record something.
3: Last but not the least, you need a lot of freespace as video recording
is a space consuming task
First install the mplayer and mencoder as root.
now, if you have only one TV card in your computer
you will find it under /dev/video0 configured as
a V4L device. We can write the following
command to check if the TV card is working.
mplayer tv:// -tv driver=v4l2:input=0:norm=pal:width=640:height=480:device=/dev/video0:\
freq=775.25:adevice=/dev/dsp1:forceaudio:audiorate=32000
If there is no sound check the followings.
1:Check your loopback audio cable from the TV card sound out, see if it is connected to
the Line In of the sound card.
2: From alsamixer or kmix or any other sound mixer unmute the line in and increase
the sound.
you can use "h" and "k" to browse the other channels.
Now we will record a test video.
Now become root or sudo and perform the following steps.
Copy this script to a file named vcrui.sh
#!/bin/bash
ROOT_UID=0
NARGS=1
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "You must be root to record a program"
exit $E_NOTROOT
fi
if [ $# -ge "$NARGS" ]
then
echo "Feature Not Implemented"
exit $E_NO_ARGS_SUPPORTED
fi
echo "Enter channel number::"
read xnumber
echo "Enter Program Name::"
read xname
echo "Enter duration in Seconds::"
read xduration
exec ./vr.sh $xnumber $xduration $xname /LinuxBackup/TV/
# EOF
And create another script file named vr.sh
with the following codes
#!/bin/bash
if [ $# -le 2 ]
then
echo "Usage: $0 channel seconds title optional->>path"
exit
fi
rmmod saa7134
modprobe saa7134
FIL=$(date +%F_%H%M)\_$1$3
WIDTH=352
HEIGHT=264
MENCODER=/usr/local/bin/mencoder
AUDIO="-oac mp3lame -lameopts cbr:br=128:mode=3"
VIDEO="-ovc lavc -lavcopts vcodec=mpeg4:mbd=2:vbitrate=700:aspect=4/3"
DSP="adevice=/dev/dsp"
TV=" -tv driver=v4l2:width=$WIDTH:height=$HEIGHT:outfmt=yuy2:device=/dev/video0:input=0:norm=PAL:chanlist=europe-west:channel=$1:$DSP"
$MENCODER tv:// $TV $VIDEO $AUDIO -endpos $2 -ffourcc divx -o "$4$FIL.avi"
sync
exit
Now, change the file type of both of the script files to executable.
chmod +x *.sh
now create the following folder path if it does not exist
/LinuxBackup/TV/
the command is
mkdir -p /LinuxBackup/TV/vcr
now open up the recording wizard with the following command
./vcrui.sh
and follow the wizard and record a 2 minutes video.
play the video with mlayer.
Now we will setup an automatic recording with the tool
NU-Tcron
Go to the following website http://supratim.nonlogic.org and download it
once downloaded, extract and compile with the command as root.
./configure;make;make install;
once installed start the service if it already has not started.
(check the instructions inside the source archive for details on hibernate hooks
. This is very important, otherwise it wouln't work properly)
Now create the following recording script (it applies for suse)(check your
distro for hibernate support and command)
file vcr.sh
#!/bin/bash
if [ $# -le 2 ]
then
echo "Usage: $0 channel seconds title optional->>path"
exit
fi
rmmod saa7134
modprobe saa7134
FIL=$(date +%F_%H%M)\_$1$3
WIDTH=352
HEIGHT=264
MENCODER=/usr/local/bin/mencoder
AUDIO="-oac mp3lame -lameopts cbr:br=128:mode=3"
VIDEO="-ovc lavc -lavcopts vcodec=mpeg4:mbd=2:vbitrate=700:aspect=4/3"
DSP="adevice=/dev/dsp"
TV=" -tv driver=v4l2:width=$WIDTH:height=$HEIGHT:outfmt=yuy2:device=/dev/video0:input=0:norm=PAL:chanlist=europe-west:channel=$1:$DSP"
$MENCODER tv:// $TV $VIDEO $AUDIO -endpos $2 -ffourcc divx -o "$4$FIL.avi"
sync
pm-hibernate
Once you create this and change permission to executable, go back to the terminal
and type
tcrontab -e
and type in a command like the following
15 7 30 3 * /bin/bash /LinuxBackup/vcr/vcr.sh 33 8100 Threshold /LinuxBackup/TV/
a b c d e ..................... f .............................. g h i ....... j ...................
where ....
a is military hour (3 PM)
b is minute
c is day of the month
d is month of the year
e we don't need to mention so we put *
f bash command for execution path of the vcr script
(make sure you create vcr folder and copy vcr.sh into it)
g channel number
h record how many seconds
i a name of the program
j archival path of the video ( a partition with a lot of free space)
with this settings a full length 2 hour movie would take
almost 700mb (a CD)
If you have set up NU-Tcron properly, you can now hibernate
(Please don't turn off the power supply)
your linux box. It will automatically wake up the movie and
go back to hibernation.
So, never miss a single movie on TV. I also have some info
on how to setup the whole thing with automatically downloaded
EPG from the internet and record your favourite movies on the
basis of IMDB rating. But that's another story. Check back to my
website and I will post that also, soon( If I find some time).
Subscribe to:
Posts (Atom)
