brainwagon "There is much pleasure in useless knowledge." — Bertrand Russell

19Apr/111

The Micro FM transmitter on copper clad (much better!)

Yesterday's video showed a very fussy version of Tetsuo Kogawa's 1 transistor FM transmitter, which worked after a fashion, but which seemed really squirrely. Almost any motion of anything caused the circuit to behave rather badly as capacitance changed, and I picked up a considerable amount of hum. Today, I rebuilt the circuit onto a piece of one sided copper clad PCB material, and it worked much better. Hardly any hum, and much less finicky. I didn't even try to add a clip lead: what you see below is the circuit just operating with whatever signal radiates from the PCB.

I'm still getting multiple copies of the output across the FM broadcast dial, so I am not sure that it's really that great of a circuit, and I'd be terrified of trying to amplify this and send it over a greater distance lest the FCC come hunting me down, but it at least works, and wasn't very hard to debug, once I got the difference in pin layout for the 2N3904 sorted out and redid the layout a bit.

Check it out!

19Apr/110

Schematic for the Micro FM transmitter

Tetsuo Kogawa's circuit is pretty well documented, but not in conventional schematic form. I decided to enter it into LTSpice to see what it could make of it, and decided to go ahead and put the schematic online here, with perhaps a few comments:

I've set this up more or less as I built the circuit: in my circuit C1 is a small air variable cap that goes up to about 18pF, so I've set it to 12pF here. I use a 9V supply, so that's what I put in for V2. I changed the power supply bypass cap to be 0.1uF instead of 0.01uF, since I have a bag of 0.1uF ones, and it doesn't seem to affect the circuit. The L1 value of 0.08uH was determined by plugging numbers into the formula for an air wound solenoid coil: it's probably only very roughly what the inductance actually is. Instead of the 2SC2001, I went ahead and put in the 2n3904 that I used. V1 is supposed to model the audio input, supplying a 1000 Hz, 1V amplitide sine wave to the modulation input. The output should be tapped from the emitter of Q1.

I'm going to experiment with the circuit a bit more: I'm particularly interested in jigging this up so I can figure out what the deviation is likely to be, and how it can be controlled, and how the biassing might change with a 6V supply.

19Apr/115

Watermarking and titling with ffmpeg and other open source tools…

I've received two requests for information about my "video production pipeline", such as it is. As you can tell by my videos, I am shooting with pretty ugly hardware, in a pretty ugly way, with minimal (read "no") editing. But I did figure out a pretty nice way to add some watermarks and overlays to my videos using open source tools like ffmpeg, and thought that it might be worth documenting here (at least so I don't forget how to do it myself).

First of all, I'm using an old Kodak Zi6 that I got for a good price off woot.com. It shoots at 1280x720p, which is a nominally a widescreen HD format. But since ultimately I am going to target YouTube, and because the video quality isn't all that astounding anyway, I have chosen in all my most recent videos to target a 480 line format, which (assuming 16:9) aspect ratio means that I need tor resize my videos down to 854x480. The Zi6 saves in a Quicktime container format, using h264 video and AAC audio at 8Mbps and 128kbps respectively.

For general mucking around with video, I like to use my favorite Swiss army knife: ffmpeg. It reads and writes a ton of formats, and has a nifty set of features that help in titling. You can try installing it from whatever binary repository you like, but I usually find out that I need to rebuild it to include some option that the makers of the binary repository didn't think to add. Luckily, it's not really that hard to build: you can follow the instructions to get a current source tree, and then it's simply a matter of building it with the needed options. If you run ffmpeg by itself, it will tell you what the configuration options it used for compilation. For my own compile, I used these options:

--enable-libvpx --enable-gpl --enable-nonfree --enable-libx264 --enable-libtheora --enable-libvorbis 
--enable-libfaac --enable-libfreetype --enable-frei0r --enable-libmp3lame

I enabled libvpx, libvorbis and libtheora for experimenting with webm and related codecs. I added libx264 and libfaac so I could do MPEG4, mp3lame so I could encode to mp3 format audio, most important for this example, libfreetype so it would build video filters that could overlay text onto my video. If you compile ffmpeg with these options, you should be compatible with what I am doing here.

It wouldn't be hard to just type a quick command line to resize and re-encode the video, but I'm after something a bit more complicated here. My pipeline resizes, removes noise, does a fade in, and then adds text over the bottom of the screen that contains the video title, my contact information, and a Creative Commons banner so that people know how they can reuse the video. To do this, I need to make use of the libavfilter features of ffmpeg. Without further ado, here's the command line I used for a recent video:

#!/bin/sh
./ffmpeg -y -i ../Zi6_4370.MOV -sameq -aspect 16:9 -vf "scale=854:480, fade=in:0:30, hqdn3d [xxx]; color=0x33669955:854x64 [yyy] ; [xxx] [yyy] overlay=0:416, drawtext=textfile=hdr:fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf:x=10:y=432:fontsize=16:fontcolor=white [xxx] ; movie=88x31.png [yyy]; [xxx] [yyy] overlay=W-w-10:H-h-16" microfm.mp4

So, what does all this do? Well, walking through the command: -y says to go ahead and overwrite the output file. -i specifies the input file to be the raw footage that I transferred from my Zi6. I specified -sameq to keep the quality level the same for the output:: you might want to specify an audio and video bitrate separately here, but I figure retaining the original quality for upload to YouTube is a good thing. I am shooting 16:9, so I specify the aspect ratio with the next argument.

Then comes the real magic: the -vf argument specifies a rather long command string. You can think of it as a series of chains, separated by semicolons. Each command in the chain is separated by commas. Inputs and outputs are specified by names appearing inside square brackets. Read the rather terse and difficult documentation if you want to understand more, but it's not too hard to walk through what the chains do. From 'scale" to the first semicolon, the input video (implicit input to the filter chain) we resize the video to the desired output size, fade in from black over the first 30 frames, and then run the high quality 3d denoiser, storing the result in register xxx. The next command creates a semi-transparent background color card which is 64 pixels high and the full width of the video, storing it in y. The next command takes the resized video xxx, and the color card yyy, and overlays the color at the bottom. We could store that in a new register, but instead we simply chain on a drawtext command. It specifies an x, y, and fontfile, as well as a file "hdr" which contains the text that we want to insert. For this video, that file looks like:

The (too simple) Micro FM transmitter on a breadboard
http://brainwagon.org | @brainwagon | mailto:brainwagon@gmail.com

The command then stores the output back in the register [xxx]. The next command reads a simple png file of the Creative Commons license and makes it available as a movie in register yyy. In this case, it's just a simple .png, but you could use an animated file if you'd rather. The last command then takes xxx and yyy and overlays them so that the copyright appears in the right place.

And that's it! To process my video, I just download from the camera to my linux box, change the title information in the file "hdr", and then run the command. When it is done, I'm ready to upload the file to YouTube.

A couple of improvements I have yet to add to my usual pipeline: I don't really like the edge of the transparent color block: it would be nicer to use a gradient. I couldn't figure out how to synthesize one in ffmpeg, but it isn't hard if you have something like the netpbm utilities:

#!/bin/sh

pamgradient black black rgb:80/80/80 rgb:80/80/80 854 16 | pamtopnm > grad1.pgm
ppmmake rgb:80/80/80 854 48 | ppmtopgm > grad2.pgm
pnmcat -tb grad1.pgm grad2.pgm > alpha.pgm
ppmmake rgb:33/66/99 854 64 > color.ppm
pnmtopng -force -alpha alpha.pgm color.ppm > mix.png

Running this command builds a file called 'mix.png', which you can read in using the movie node in the avfilter chain, just as I did for the Creative Commons logo. Here's an example:



If I were a real genius, I'd merge this whole thing into a little python script that could also manage the uploading to YouTube.

If this is any help to you, or you have refinements to the basic idea that you'd like to share, be sure to add your comments or links below!