by Theo Verelst
Maybe a bit of a specialistic page, but fun.
I tried using tcl to set up a connection to a remote machine, over a simple ethernet connection, where a video file would be transfered with two short tcl scripts.
The one machine, with the video file on it, would run this script:
set ss [socket -server servvid 1234] proc servvid {s i p} { global argv puts "connection from $i" flush stdout # set f [open h:/dinsd2b.wmv r] set f [open [lindex $argv 0] r] fconfigure $s -translation binary fconfigure $f -translation binary fileevent $s readable "puts \"read: \[gets $s\]\" ; flush stdout if \[eof $s\] { close $s close $f puts {End of file.}} " after 2000 fileevent $s writable "fcopy $f $s -size 1024 if \[eof $s\] { close $s close $f puts {End of file.}} " } vwait forever
called like this (I used cygwin):
tclsh servvid.tcl i:/Videos/Thunderbold\ and\ Lightfoot.mpg
where the mpeg file is a large file (the example is about 7 Gigabytes), which is the reason it's not simply copied to the other machine. It may not have enough free disc space, and even over 100baseT ethernet it would take some time to copy.
On the other machine, I used another small tcl script to take data from the above dedicated server script, and copy it to stdout:
set s [socket 192.168.0.1 1234] fconfigure $s -translation binary fconfigure stdout -translation binary fileevent $s readable "puts -nonewline stdout \[read $s 1024\]; flush stdout" vwait forever
this script is called like this to pipe it's output to mplayer a linux/windows video player of good visual quality:
tclsh socktostdout.tcl | mplayer -
With a from-tv recorded movie in (D1) DVD quality, on 'consumer' machines (not too slow) this works neat, except one cannot wind through the video, it starts and then runs, and can be paused (press p in mplayer) but always runs from the beginning.
Remarkably enough, with this 6Mb/s movie material, there are no glitches or hickups, display is nice and smooth.
File sharing of some kind would be possible as alternative, of course, instead of the socket connection, but the machine I used as server has an internet connection, and I don't want to take the risk of anything shared on it. The above script allows serving of only a specific file and nothing else, so can be considered safe, just like that I use pcom with local-only connections to start xterms.
Using Dune
Setup diagram (using BWise)
Dune [L1 ] is a set of programs to under linux (at least) control a Pinnacle compatible USB TV mpeg encoder, for a few hundred $s it works fine.
Install dune and on can pipe the output of dunerec to for instance mplayer.
I have this on a machine near a cable/sattelite connection, and can watch dvd quality encoded TV over a network with mplayer using the following tcl scripts.
On the pinnacle side this script should be run, after duneinit has been run (possibly twice) to make the usb connection feed the video box with the right usb driver.
set ss [socket -server servvid 1234] proc servvid {s i p} { global argv puts "connection from $i" flush stdout # set f [open h:/dinsd2b.wmv r] # set f [open [lindex $argv 0] r] fconfigure $s -translation binary set f [ open "| dunerec -a [lindex $argv 0] -t dvd -i 0 -R -" r] # alternatively this enables the front side composite video/audio inputs # set f [ open "| dunerec -a [lindex $argv 0] -i 2 -R -" r] fconfigure $f -translation binary fileevent $s readable "puts \"read: \[gets $s\]\" ; flush stdout if \[eof $s\] { close $s close $f puts {End of file.}} " after 2000 fileevent $s writable "fcopy $f $s -size 1024 if \[eof $s\] { close $s close $f puts {End of file.}} " }
like this froma command line:
tclsh servvid.tcl 544250
Where the latter is the frequency of the channel.
The receiving PC runs this script:
set s [socket 192.168.1.33 1234] fconfigure $s -translation binary -buffering full fconfigure stdout -translation binary -buffering full fileevent $s readable "puts -nonewline stdout \[read $s 10240\]; flush stdout" vwait forever
like this:
tclsh socktostdout2.tcl | mplayer -cache 4096 -
Image quality is great, and can be varied, recording is also possible (a tee ?) the tcl scripts don't take much processing time, the linux encoder is hardly noticable. It waits for a connection which when it is made over the socket keeps dunerec running. After mplayer has been killed, it possibly has to be killed by control-c from the commandline, too. After that it can be started again indefinitely, and the serverside dunerec will only work during actual connections.
tb 20090205 - For those like me, who use a different DVB-Recevier with Linux, the server side part can use tzap and ts2ps to substitute the dune suite of programs.
# Configure here set TZAP /usr/bin/tzap set TS2PS /usr/bin/ts2ps # Kill previous instance of "tzap" catch {exec killall -KILL tzap; sleep 1} # Call tzap to zap to $1 and wait 2 secs for sync exec $TZAP -r [lindex $argv 0] >/dev/null 2>/dev/null & exec sleep 2 puts "Awaiting connection..." flush stdout set ss [socket -server servvid 8111] proc servvid {s i p} { global argv puts "\nconnection from $i" flush stdout set f [open "|$TS2PS /dev/dvb/adapter0/dvr0 0 0" r] fconfigure $f -translation binary flush stdout fconfigure $s -translation binary fileevent $s readable "puts \"read: \[gets $s\]\" ; flush stdout if \[eof $s\] { close $s close $f puts {End of file.}} " after 2000 fileevent $s writable "fcopy $f $s -size 128 if \[eof $s\] { close $s close $f puts {End of file.}} " } vwait forever
tb 20090205 - This is really interesting :) - Here's another one which scales and encodes from DVB to MPEG4 using mencoder. It is tweaked to serv over a DSL :) - I had best results on the client side using xine instead of mplayer.
puts "Awaiting connection..." flush stdout set ss [socket -server servvid 8111] proc servvid {s i p} { global argv puts "\nconnection from $i" flush stdout # the following strings are setting # encoding parameters for serving one # client over DSL (60Kb upstream) set scale "-vf scale -zoom -xy 280 -ofps 15" set vcodec "-ovc lavc -lavcopts vcodec=msmpeg4:vbitrate=384:vhq" set acodec "-oac mp3lame" set ch [open "|mencoder dvb://[lindex $argv 0] -really-quiet -msglevel all=-1 $scale $vcodec $acodec -o -" r] puts "" flush stdout fconfigure $ch -translation binary fconfigure $s -translation binary fileevent $s readable "puts \"read: \[gets $s\]\" ; flush stdout if \[eof $s\] { close $s close $ch puts {End of file.}} " after 2000 fileevent $s writable "fcopy $ch $s -size 128 if \[eof $s\] { close $s close $ch puts {End of file.}} " } vwait forever
See also: