Video editing using ffmpeg and audacity
21 mar. 2013Lately I have made some recordings of lectures using my Sanyo HD1000 camera, using the docking station as mount and powering it since it only runs for about 2 hours on battery. Even though I'm using a 16 GiB memory card, I can not record for more than about 1 hour in 720p resolution because of the 4 GiB file size limitation in FAT.
The video format is MP4 containing H.264 for video and AAC for audio. Apple iMovie accepts the format, but insists on cutting everything into small pieces. Editing is a nightmare and it's terrible slow because of all the prerendering. The audio contains a lot of fan noise because the lectures are in a computer lab.
The best solution I have found is to combine the "Swiss army knife" terminal program ffmpeg, now renamed to avconv in Ubuntu. I also use Audacity for audio noise reduction:
sudo apt-get install ffmpeg
sudo apt-get install libavcodec-extra-53
In order to avoid any audio/video synchronization problems, it's best to start with the cutting. I had parts I did not want in the beginning and in the end of each clip. This command would let me extract parts of a movie file:
avconv -ss 00:05:10 -i "SANY0002.MP4" -t 00:40:20 -c copy "part2.mp4"
We cut from 5 min and 10 seconds from file input and end at 40 min and 20 seconds. Video and audio is copied and the output file is output. Repeat this for all the parts you need. Next I extract all the audio to separate files for import in Audacity:
avconv -i "SANY0002.MP4" -acodec copy "part2.aac"
The next step is in audacity. Drag all the audio parts into the program, push F5 to enable dragging and dropping, align the clips so that the all the clips are spread out in time in the correct order. They will "snap" to the edges. In order to remove noise, press F1 to go back to selection mode, select any small part of half of a second or so that only contains the noise you want to remove. Go to "effect" and "noise removal" and select the button called "get noise profile". The window will go away, and you must now select all of the clips (Ctrl + A) and go back to the "noise removal" window. I had to work with the setting for a while, and ended up using noise reduction at 23 dB, sensitivity at 0.00 dB, frequency smoothing at 240Hz and Attack at 0.3 secs. Noise to "remove". Preview for testing and apply it. It will take a minute or two processing. Then I saved it using mp3 codec at 96kbps using the export function.
When connected to the power grid I get a lot of constant hum on the audio, even with external microphone. Since the power grid is 50 Hz in Norway, a notch filter by 50 Hz and it's harmonics can be used, and by applying it before I do the general noise reduction mentioned above, I've been able to remove quite intrusive noise. Using "Nyquist prompt" (source link)
(notch2
(notch2
(notch2
(notch2
(notch2
s
250 10)
200 8)
150 4)
100 2)
50 1)
Back to the video parts, lets compress them a bit, without sound (-an), reducing the resolution to 960x540, using x264 video codec with veryfast and quality 24. (Better quality per bit can be reached by using slower methods combined with several passes.
avconv -i "part2.mp4" -an -s 960x540 -c:v libx264 -preset veryfast -tune film -crf 24 "part2_comp.mp4"
There are little movement so with these settings I get about 1.5 hours down to 200 MiB or around 300kbps with acceptable picture quality.
All that is left now is to merge all the compressed video clips and add back the voice now in mp3 and with less noise. The MP4 container can not be merged directly, but we can put the content of it into mpeg containers and then merge them and put them back into a MP4 container: For every file
avconv -i "part2_comp.mp4" -map 0 -c copy -f mpegts -bsf h264_mp4toannexb "part2.ts"
Then combine:
avconv -i "concat:part1.ts|part2.ts|part3.ts|part4.ts" -c copy "combined_video.mp4"
and add audio:
avconv -i "combined_video.mp4" -i "audio_nr.mp3" -c copy "final_video.mp4"
and that's it!
For replacing the audio
avconv -i <input_video> -i <input_audio> -map 0:1 -map 1:0 -vcodec copy -acodec copy <output>