From 3a2efdff36bf54e4e329d4359f175e178150049b Mon Sep 17 00:00:00 2001 From: Kale Good Date: Fri, 15 Feb 2013 10:37:49 -0500 Subject: [PATCH] First Commit --- ly2video.py | 161 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 147 insertions(+), 14 deletions(-) diff --git a/ly2video.py b/ly2video.py index 17ba9b8..aa99a63 100755 --- a/ly2video.py +++ b/ly2video.py @@ -370,7 +370,7 @@ def generateTitle(titleText, width, height, ttfFile, fps, titleLength): if not os.path.exists("title"): os.mkdir("title") - totalFrames = int(round(fps * titleLength)) + totalFrames = 1 progress("TITLE: ly2video will generate approx. %d frames." % totalFrames) # font for song's name, args - font type, size @@ -395,6 +395,57 @@ def generateTitle(titleText, width, height, ttfFile, fps, titleLength): (totalFrames, totalFrames)) return 0 +def generateBeats(width, height, ttfFile, beatstempo, beats, fps): + """ + Generates frames with count-in beats. + + Params: + - width: pixel width of frames (and video) + - height: pixel height of frames (and video) + - ttfFile: path to TTF file to use for title text + - fps: frame rate (frames per second) of final video + - beatstempo: tempo + - beats number of count-in beats + """ + + #I had the zero displayed because it otherwise seemed very abrupt. A click-track could help this. A nice feature would be option to make last note red (or other color). + + # save folder for frames + if not os.path.exists("beats"): + os.mkdir("beats") + + totalFrames = int(round((60.000/beatstempo) * fps)) + + for currentBeat in range(beats+1): + + printBeat = currentBeat + + # create image of title screen + titleScreen = Image.new("RGB", (width, height), (255,255,255)) + # it will draw text on titleScreen + drawer = ImageDraw.Draw(titleScreen) + + progress("Beats: ly2video will generate approx. %d frames." % totalFrames) + # font for beat args - font type, size + nameFont = ImageFont.truetype(ttfFile, height / 10) + + # args - position of left upper corner of rectangle (around text), text, font and color (black) + drawer.text(((width - nameFont.getsize("%d" % printBeat)[0]) / 2, + (height - nameFont.getsize("%d" % printBeat)[1]) / 2 - height / 25), + "%d" % printBeat, font=nameFont, fill=(0,0,0)) + + # generate needed number of frames (= (60/tempo) * fps) + for frameNum in xrange(totalFrames): + titleScreen.save(tmpPath("beats", "frame%d.png" % ((currentBeat*totalFrames)+frameNum))) + + progress("Beats: Generating title screen has ended. (%d/%d)" % + (totalFrames, totalFrames)) + + + return 0 + + + def staffSpacesToPixels(ss, dpi): staffSpacePoints = GLOBAL_STAFF_SIZE / 4 points = ss * staffSpacePoints @@ -1183,7 +1234,7 @@ def genWavFile(timidity, midiPath): bug("TiMidity++ failed to generate %s" % wavExpected) return wavExpected -def generateSilence(length): +def generateTitleSilence(length): """ Generates silent audio for the title screen. @@ -1203,7 +1254,7 @@ def generateSilence(length): Subchunk2Size = length * sample * channels * bps/8 ChunkSize = 4 + (8 + Subchunk1Size) + (8 + Subchunk2Size) - fSilence = open("silence.wav", "w") + fSilence = open("titlesilence.wav", "w") fSilence.write("".join([ 'RIFF', # ChunkID (magic) # 0x00 @@ -1223,7 +1274,52 @@ def generateSilence(length): '\0'*Subchunk2Size ])) fSilence.close() - return "silence.wav" + return "titlesilence.wav" + +def generateBeatSilence(beatstempo, beats): + """ + Generates silent audio for the beat screens. + + author: Mister Muffin, + http://blog.mister-muffin.de/2011/06/04/generate-silent-wav/ + + Params: + - beatstempo: tempo + - beats beats of count-in + """ + + #there should be an option to have a "click" on every beat (it should be default, imo). + + # + channels = 2 # number of channels + bps = 16 # bits per sample + sample = 44100 # sample rate + ExtraParamSize = 0 + Subchunk1Size = 16 + 2 + ExtraParamSize + Subchunk2Size = int((60.000/beatstempo)*beats+1.000) * sample * channels * bps/8 + ChunkSize = 4 + (8 + Subchunk1Size) + (8 + Subchunk2Size) + + fSilence = open("beatsilence.wav", "w") + + fSilence.write("".join([ + 'RIFF', # ChunkID (magic) # 0x00 + pack(' '%s'" % (titlePath, notesPath, joinedPath), shell=True) + safeRun("cat '%s' '%s' '%s' > '%s'" % (titlePath, beatsPath, notesPath, joinedPath), shell=True) + #didn't test this in windows elif sys.platform.startswith("win"): - os.system('copy "%s" /B + "%s" /B "%s" /B' % (titlePath, notesPath, joinedPath)) + os.system('copy "%s" /B + "%s" /B + "%s" /B "%s" /B' % (titlePath, beatsPath, notesPath, joinedPath)) # create output file cmd = [ ffmpeg, "-i", joinedPath, "-q:v", str(options.quality), + "-b:a", "320k", outputFile ] safeRun(cmd, exitcode=16) @@ -1862,6 +1989,12 @@ def main(): generateTitle(titleText, options.width, options.height, options.titleTtfFile, fps, options.titleDuration) output_divider_line() + + # generate beats screen + if options.beatsAtStart: + generateBeats(options.width, options.height, + options.titleTtfFile, options.beatstempo, options.beats, fps) + output_divider_line() # generate notes leftMargin, rightMargin = options.cursorMargins.split(",")