Imagine Dragons' Radioactive
By HexHammer
Record the audio
- Record 'radioactive' on guitar in one take, save it using arecord. It's best to use AAC format for this, MP4 seems to prefer it :
$ cd Desktop
$ mkdir radioactive
$ cd radioactive
$ arecord -f S16_LE -r 44100 -c 2 -V stereo radioactive.aac --> cd quality, 2 channels, stereo vumeter.
Film the video
- Film each hand separately using Kazam to capture AIMos while 'playing' along to the AAC.
- Film my face singing along to the recording the same way, using the capture audio option to record the speakers, not the mic. The audio is to be used as a cue marker later :
$ kazam &
$ cd ../aimos/motion
$ ./motion.sh
- Using nano, write out the lyrics into a file (each piece on a new line, optionally followed by a comma and the colour.
$ cd ../radioactive
$ nano radioactivelyrics.txt
I'm waking up,white
to ash and dust
I wipe my brow
and I sweat my rust
I'm breathing in
the chemicals
I'm breaking in
shaping up
then checking out
on the prison bus
This is it
the apocalypse
Whoa-oh
I'm waking up,yellow
I feel it
in my bones
Enough to make
my systems blow
Welcome to the new age...
- While playing back the recording, use Kazam to capture the Python window while using the spacebar to step through the lyrics file. Use the capture audio option again :
$ kazam &
$ python pygamelyrics.py
>> import pygame
>> from pygame.locals import *
>> pygame.init()
>> pygame.font.init()
>> legend=pygame.font.SysFont('Sans', 72,bold=True)
>> w=1024; h=768
>> window = pygame.display.set_mode((w,h))
>> pygame.display.set_caption(str(w)+","+str(h))
>> screen = pygame.display.get_surface()
>> lfile=open('radioactivelyrics.txt','r')
>> lyrics=list(lfile)
>> lfile.close()
>> print 'ready? click on the display and press space.'
>> waiting=True
>> while waiting:
>> events = pygame.event.get()
>> for event in events:
>> if event.type == KEYDOWN:
>> if event.key == K_SPACE: waiting=False
>> print 'running...'
>> cr=255; cg=255; cb=255
>> for l in lyrics:
>> waiting=True
>> if ',' in l: # current text colour can be specified after a comma
>> col=l.split(',')[1].strip() # in the radioactivelyrics.txt file
>> if col=='white': cr=255; cg=255; cb=255
>> if col=='red': cr=255;cg=0;cb=0
>> if col=='yellow': cr=255;cg=255;cb=192
>> if col=='green': cr=0;cg=255;cb=0
>> print l.split(',')[0]+'<'+col+'>'
>> r=cr; g=cg; b=cb
>> while waiting:
>> events=pygame.event.get()
>> for event in events:
>> if event.type==KEYDOWN:
>> if event.key==K_SPACE: waiting=False
>> pygame.draw.rect(screen,(0,0,0),(0,0,w,h))
>> txt=l.split(',')[0].strip().lower()
>> text=legend.render(txt, True, (r,g,b))
>> tw=text.get_width()
>> th=text.get_height()
>> screen.blit(text,((w/2)-(tw/2),(h/2)-(th/2)))
>> pygame.display.flip()
>> r=r-1; g=g-1; b=b-1
>> if r<0: r=0
>> if g<0: g=0
>> if b<0: b=0
>> print '\ndone'
>> sleep(5)
>> pygame.display.quit()
Edit the video
- Make a folder for each channel, then use avconv to split the mp4 files up into frames in the channel folders. If you dont have avconv you can replace it with ffmpeg, they are completely interoperable :
$ mkdir face
$ mkdir left
$ mkdir right
$ mkdir lyrics
$ avconv -i face.mp4 -f image2 face/%04d.png or use ffmpeg -i face.mp4 -f image2 face/%04d.png
$ avconv -i left.mp4 -f image2 left/%04d.png
$ avconv -i right.mp4 -f image2 right/%04d.png
$ avconv -i lyrics.mp4 -f image2 lyrics/%04d.png
- Use mplayer to determine the start point of the audio in each mp4 in seconds, multiply by fps (15).
- Delete the leading frames from each folder and rename the images starting with 0000.png. Now all the frames are lined up on the original AAC audio across the 4 folders :
$ mplayer left.mp4 --> get frame number of start of audio.
$ cd left
$ ls >files
$ python ../r_delete.py
>> import os
>> fil=open('files',r)
>> lst=list(fil)
>> for f in fil:
>> os.remove(line.strip())
$ rm files
$ ls >files
$ python ../r_rename.py
>> import os
>> n=0
>> for f in list(open('files','r')):
>> nam='0000'+str(n)
>> if '.' in f: os.rename(f.strip(),nam[len(nam)-4:]+'.png')
>> n+=1
$ rm files
$ cd ..
- Repeat this for each folder of images.
- Decide which pieces of video should play, and when. Delete the unwanted frames from each folder. Obviously here the lyrics will play right through so this is left intact.
$ cd left
$ ls >files
$ nano files --> delete any unwanted frames from the list
$ python ../r_delete.py
>> import os
>> n=0
>> for f in list(open('files','r')):
>> nam='0000'+str(n)
>> os.remove(line.strip())
>> n+=1
$ rm files
$ cd ..
- Repeat this for each folder of images.
- Open the folders and iterate through the frame numbers. If any images with the same frame number across the folders are found, they are OR'd together and written as a single frame to the output folder. This blends the 4 channels together :
$ python radioactive.py
>> import pygame,os
>> from pygame.locals import *
>> from time import sleep
>> pygame.init()
>> w=640; h=480
>> window = pygame.display.set_mode((w,h))
>> pygame.display.set_caption(str(w)+","+str(h))
>> screen = pygame.display.get_surface()
>> tracklen=3465
>> os.mkdir('output')
>> def mix(src1,src2):
>> dst=''
>> for n in range(len(src1)):
>> s1=ord(src1[n])
>> s2=ord(src2[n])
>> dst=dst+chr(s1|s2)
>> return dst
>> for n in range(tracklen+1):
>> nam='0000'+str(n)
>> if os.path.isfile('lyrics/'+nam[len(nam)-4:]+'.png'):
>> img=pygame.image.load('lyrics/'+nam[len(nam)-4:]+'.png')
>> scl=pygame.transform.scale(img,(w,h))
>> lyric=pygame.image.tostring(scl,'RGB')
>> else:
>> lyric=''
>> if os.path.isfile('left/'+nam[len(nam)-4:]+'.png'):
>> img=pygame.image.load('left/'+nam[len(nam)-4:]+'.png')
>> scl=pygame.transform.scale(img,(w,h))
>> left=pygame.image.tostring(scl,'RGB')
>> else:
>> left=''
>> if os.path.isfile('right/'+nam[len(nam)-4:]+'.png'):
>> img=pygame.image.load('right/'+nam[len(nam)-4:]+'.png')
>> scl=pygame.transform.scale(img,(w,h))
>> right=pygame.image.tostring(scl,'RGB')
>> else:
>> right=''
>> if os.path.isfile('face/'+nam[len(nam)-4:]+'.png'):
>> img=pygame.image.load('face/'+nam[len(nam)-4:]+'.png')
>> scl=pygame.transform.scale(img,(w,h))
>> face=pygame.image.tostring(scl,'RGB')
>> else:
>> face=''
>> print nam[len(nam)-4:]+'.png'+' lyric:'+str(len(lyric))+' left:'+str(len(left))+' right:'+str(len(right))+' face:'+str(len(face))
>> if lyric!='':
>> out=lyric
>> if left!='': out=mix(out,left)
>> if right!='': out=mix(out,right)
>> if face!='': out=mix(out,face)
>> surf=pygame.image.fromstring(out,(640,480),'RGB')
>> pygame.image.save(surf,'output/'+nam[len(nam)-4:]+'.png')
>> screen.blit(surf,(0,0))
>> pygame.display.flip()
- Use avconv again to mux the frames in the output folder into an MP4 video file, and then mux the MP4 video and AAC audio into a single mp4 :
$ cd output
$ avconv -r 15 -i %04d.png output.mp4
$ avconv -i output.mp4 -i radioactive.aac -map 0:0 -map 1:0 -vcodec copy -acodec copy radioactive.mp4
- Finally play back the finished video.
$ mplayer radioactive.mp4