commit ea0c29849dc1ee2cca9713fc4ef46badf6d2d40d
parent 7b5af2958b194b7f36210c58c98400e01fd35b29
Author: rbckman <rob@tarina.org>
Date:   Fri, 31 Dec 2021 13:19:22 +0000
add fps and h264 quality settings to menu
Diffstat:
5 files changed, 165 insertions(+), 33 deletions(-)
diff --git a/extras/youtubelive.sh b/extras/youtubelive.sh
@@ -0,0 +1 @@
+raspivid -o - -t 0 -w 1920 -h 816 -vf -hf -fps 25 -b 3000000 | ffmpeg -re -ar 44100 -acodec pcm_s16le -f alsa -ac 1 -i hw:0 -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/j1cs-7hac-ygrj-5gaq-3m5b
diff --git a/extras/ytstream.py b/extras/ytstream.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3 
+import subprocess 
+import picamerax
+import time 
+YOUTUBE="rtmp://a.rtmp.youtube.com/live2/" 
+KEY='j1cs-7hac-ygrj-5gaq-3m5b' 
+stream_cmd = 'ffmpeg -f h264 -r 25 -i - -itsoffset 5.5 -fflags nobuffer -f alsa -ac 1 -i hw:0 -vcodec copy -acodec libmp3lame -ar 44100 -map 0:0 -map 1:0 -strict experimental -f flv ' + YOUTUBE + KEY 
+stream = subprocess.Popen(stream_cmd, shell=True, stdin=subprocess.PIPE) 
+camera = picamerax.PiCamera(resolution=(640, 480), framerate=25) 
+try: 
+  now = time.strftime("%Y-%m-%d-%H:%M:%S") 
+  camera.framerate = 25 
+  camera.vflip = True 
+  camera.hflip = True 
+  camera.start_recording(stream.stdin, format='h264', bitrate = 2000000) 
+  while True: 
+     camera.wait_recording(1) 
+except KeyboardInterrupt: 
+     camera.stop_recording() 
+finally: 
+  camera.close() 
+  stream.stdin.close() 
+  stream.wait() 
+  print("Camera safely shut down") 
+  print("Good bye") 
diff --git a/gui/src/main.c b/gui/src/main.c
@@ -180,19 +180,19 @@ int main(void)
                             render_subtitle(img, line, text_size, row1, y_offset2, color);
                             row1 += read * space + morespace;
                         }
-                        if (linenr >= 7 && linenr <= 10){
+                        if (linenr >= 7 && linenr <= 12){
                             render_subtitle(img, line, text_size, row2, y_offset3, color);
                             row2 += read * space + morespace;
                         }
-                        if (linenr >= 11 && linenr <= 16){
+                        if (linenr >= 13 && linenr <= 20){
                             render_subtitle(img, line, text_size, row3, y_offset4, color);
                             row3 += read * space + morespace;
                         }
-                        if (linenr >= 17 && linenr <= 23){
+                        if (linenr >= 21 && linenr <= 27){
                             render_subtitle(img, line, text_size, row4, y_offset5, color);
                             row4 += read * space + morespace;
                         }
-                        if (linenr >= 24 && linenr <= 40){
+                        if (linenr >= 28 && linenr <= 40){
                             render_subtitle(img, line, text_size, row5, y_offset6, color);
                             row5 += read * space + morespace;
                         }
diff --git a/gui/tarinagui.bin b/gui/tarinagui.bin
Binary files differ.
diff --git a/tarina.py b/tarina.py
@@ -84,7 +84,7 @@ def main():
         os.makedirs(filmfolder)
     tarinafolder = os.getcwd()
     #MENUS
-    menu = 'FILM:', 'SCENE:', 'SHOT:', 'TAKE:', '', 'SHUTTER:', 'ISO:', 'RED:', 'BLUE:', 'BRIGHT:', 'CONT:', 'SAT:', 'FLIP:', 'BEEP:', 'LENGTH:', 'HW:', 'CH:', 'MIC:', 'PHONES:', 'COMP:', 'TIMELAPSE', 'LENS:', 'DSK:', 'SHUTDOWN', 'SRV:', 'WIFI:', 'UPDATE', 'UPLOAD', 'BACKUP', 'LOAD', 'NEW', 'TITLE', 'LIVE:'
+    menu = 'FILM:', 'SCENE:', 'SHOT:', 'TAKE:', '', 'SHUTTER:', 'ISO:', 'RED:', 'BLUE:', 'FPS:', 'Q:', 'BRIGHT:', 'CONT:', 'SAT:', 'FLIP:', 'BEEP:', 'LENGTH:', 'HW:', 'CH:', 'MIC:', 'PHONES:', 'COMP:', 'TIMELAPSE', 'LENS:', 'DSK:', 'SHUTDOWN', 'SRV:', 'WIFI:', 'UPDATE', 'UPLOAD', 'BACKUP', 'LOAD', 'NEW', 'TITLE', 'LIVE:'
     #STANDARD VALUES (some of these may not be needed, should do some clean up)
     abc = '_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0'
     keydelay = 0.0555
@@ -93,6 +93,8 @@ def main():
     awb = 'auto', 'sunlight', 'cloudy', 'shade', 'tungsten', 'fluorescent', 'incandescent', 'flash', 'horizon'
     awbx = 0
     awb_lock = 'no'
+    fps = 24.999
+    quality = 26
     headphoneslevel = 40
     miclevel = 50
     recording = False
@@ -150,7 +152,7 @@ def main():
     diskleft = str(int(disk.f_bavail * disk.f_frsize / 1024 / 1024 / 1024)) + 'Gb'
     #START INTERFACE
     startinterface()
-    camera = startcamera(lens)
+    camera = startcamera(lens,fps)
     #LOAD FILM AND SCENE SETTINGS
     try:
         filmname = getfilms(filmfolder)[0][0]
@@ -251,9 +253,22 @@ def main():
                     imagename = foldername + filename + '.jpeg'
                     overlay = displayimage(camera, imagename, overlay)
                     camera.start_preview()
+            #DUB SHOT
+            elif pressed == 'middle' and menu[selected] == 'SHOT:':
+                newdub = clipsettings(filmfolder, filmname, scene, shot, plughw)
+                if newdub:
+                    camera.stop_preview()
+                    renderfilename, newaudiomix = rendershot(filmfolder, filmname, scene, shot)
+                    playdub(renderfilename, 'dub')
+                    run_command('sox -V0 -G /dev/shm/dub.wav ' + newdub)
+                    vumetermessage('new scene dubbing made!')
+                    camera.start_preview()
+                    time.sleep(1)
+                else:
+                    vumetermessage('see ya around!')
             #DUB SCENE
             elif pressed == 'middle' and menu[selected] == 'SCENE:':
-                newdub = clipsettings(filmfolder, filmname, scene, plughw)
+                newdub = clipsettings(filmfolder, filmname, scene, 0, plughw)
                 if newdub:
                     camera.stop_preview()
                     renderfilename, newaudiomix = renderscene(filmfolder, filmname, scene)
@@ -266,7 +281,7 @@ def main():
                     vumetermessage('see ya around!')
             #DUB FILM
             elif pressed == 'middle' and menu[selected] == 'FILM:':
-                newdub = clipsettings(filmfolder, filmname, '', plughw)
+                newdub = clipsettings(filmfolder, filmname, 0, 0, plughw)
                 if newdub:
                     camera.stop_preview()
                     renderfilename = renderfilm(filmfolder, filmname, comp, 0, False)
@@ -294,7 +309,7 @@ def main():
                             except:
                                 logger.warning('uploadfilm bugging')
                             startinterface()
-                            camera = startcamera(lens)
+                            camera = startcamera(lens,fps)
                             loadfilmsettings = True
                         selectedaction = 0
             #LOAD FILM
@@ -307,7 +322,7 @@ def main():
                     stopinterface(camera)
                     tarinaversion, tarinavername = update(tarinaversion, tarinavername)
                     startinterface()
-                    camera = startcamera(lens)
+                    camera = startcamera(lens,fps)
                     loadfilmsettings = True
                     selectedaction = 0
             #WIFI
@@ -315,7 +330,7 @@ def main():
                 stopinterface(camera)
                 run_command('wicd-curses')
                 startinterface()
-                camera = startcamera(lens)
+                camera = startcamera(lens,fps)
                 loadfilmsettings = True
             #NEW FILM
             elif pressed == 'middle' and menu[selected] == 'NEW' or filmname == '':
@@ -460,7 +475,7 @@ def main():
                         run_command('reset')
                         run_command('ssh -R 18888:localhost:22 tarina@tarina.org -p 13337')
                         startinterface()
-                        camera = startcamera(lens)
+                        camera = startcamera(lens,fps)
                         loadfilmsettings = True
                     except:
                         writemessage('sry! no rob help installed')
@@ -470,7 +485,7 @@ def main():
                     stopinterface(camera)
                     code.interact(local=locals())
                     startinterface()
-                    camera = startcamera(lens)
+                    camera = startcamera(lens,fps)
                     loadfilmsetings = True
                 except:
                     writemessage('hmm.. couldnt enter developer mode')
@@ -537,7 +552,7 @@ def main():
                     if os.path.isdir(foldername) == False:
                         os.makedirs(foldername)
                     os.system(tarinafolder + '/alsa-utils-1.1.3/aplay/arecord -D plughw:' + str(plughw) + ' -f S16_LE -c ' + str(channels) + ' -r44100 -vv /dev/shm/' + filename + '.wav &') 
-                    camera.start_recording(foldername + filename + '.h264', format='h264', quality=26, bitrate=5000000)
+                    camera.start_recording(foldername + filename + '.h264', format='h264', quality=quality)
                     starttime = time.time()
                     recording = True
                 elif beepcountdown > 0 and beeping == True:
@@ -726,6 +741,13 @@ def main():
             elif menu[selected] == 'CH:':
                 if channels == 1:
                     channels = 2
+            elif menu[selected] == 'FPS:':
+                if fps < 49:
+                    fps += 1
+                    camera.framerate = fps
+            elif menu[selected] == 'Q:':
+                if quality < 39:
+                    quality += 1
 
         #LEFT
         elif pressed == 'left':
@@ -844,6 +866,13 @@ def main():
             elif menu[selected] == 'CH:':
                 if channels == 2:
                     channels = 1
+            elif menu[selected] == 'FPS:':
+                if fps > 1:
+                    fps -= 1
+                    camera.framerate = fps
+            elif menu[selected] == 'Q:':
+                if quality > 10:
+                    quality -= 1
 
         #RIGHT
         elif pressed == 'right':
@@ -954,7 +983,7 @@ def main():
         #Check if menu is changed and save settings / sec
         if buttonpressed == True or recording == True or rendermenu == True:
             lastmenu = menu[selected]
-            settings = filmname, str(scene) + '/' + str(scenes), str(shot) + '/' + str(shots), str(take) + '/' + str(takes), rectime, camerashutter, cameraiso, camerared, camerablue, str(camera.brightness), str(camera.contrast), str(camera.saturation), str(flip), str(beeps), str(reclenght), str(plughw), str(channels), str(miclevel), str(headphoneslevel), str(comp), '', lens, diskleft, '', serverstate, wifistate, '', '', '', '', '', '', live
+            settings = filmname, str(scene) + '/' + str(scenes), str(shot) + '/' + str(shots), str(take) + '/' + str(takes), rectime, camerashutter, cameraiso, camerared, camerablue, str(camera.framerate), str(quality), str(camera.brightness), str(camera.contrast), str(camera.saturation), str(flip), str(beeps), str(reclenght), str(plughw), str(channels), str(miclevel), str(headphoneslevel), str(comp), '', lens, diskleft, '', serverstate, wifistate, '', '', '', '', '', '', live
             writemenu(menu,settings,selected,'')
             #Rerender menu if picamera settings change
             if settings != oldsettings:
@@ -1848,10 +1877,11 @@ def renderaudio(audiofiles, filename, dubfiles, dubmix):
     audiomerge = ['sox']
     #if render > 2:
     #    audiomerge.append(filename + '.wav')
-    for f in audiofiles:
-        audiomerge.append(f + '.wav')
-    audiomerge.append(filename + '.wav')
-    call(audiomerge, shell=False)
+    if len(audiofiles) > 1:
+        for f in audiofiles:
+            audiomerge.append(f + '.wav')
+        audiomerge.append(filename + '.wav')
+        call(audiomerge, shell=False)
     #DUBBING
     p = 1
     for i, d in zip(dubmix, dubfiles):
@@ -1883,6 +1913,76 @@ def scenefiles(filmfolder, filmname):
     #time.sleep(2)
     return files
 
+#-------------Render Shot-------------
+
+def rendershot(filmfolder, filmname, scene, shot):
+    #This function checks and calls rendervideo & renderaudio if something has changed in the film
+    #Video
+    videohash = ''
+    oldvideohash = ''
+    take = counttakes(filmname, filmfolder, scene, shot)
+    renderfilename = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/shot' + str(shot).zfill(3) + '/take' + str(take).zfill(3) 
+    filmfiles = [renderfilename]
+    scenedir = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/shot' + str(shot).zfill(3) + '/'
+    # Check if video corrupt
+    renderfix = False
+    try:
+        pipe = subprocess.check_output('mediainfo --Inform="Video;%Duration%" ' + renderfilename + '.mp4', shell=True)
+        videolenght = pipe.decode().strip()
+    except:
+        videolenght = ''
+    print('Shot lenght ' + videolenght)
+    if videolenght == '':
+        print('Okey, shot file not found or is corrupted')
+        # For backwards compatibility remove old rendered scene files
+        run_command('rm ' + renderfilename + '*')
+        renderfix = True
+    # Video Hash
+    for p in filmfiles:
+        compileshot(p)
+        videohash = videohash + str(int(countsize(p + '.mp4')))
+    print('Videohash of shot is: ' + videohash)
+    try:
+        with open(scenedir + '.videohash', 'r') as f:
+            oldvideohash = f.readline().strip()
+        print('oldvideohash is: ' + oldvideohash)
+    except:
+        print('no videohash found, making one...')
+        with open(scenedir + '.videohash', 'w') as f:
+            f.write(videohash)
+
+    #Audio
+    audiohash = ''
+    oldaudiohash = ''
+    newaudiomix = False
+    for p in filmfiles:
+        audiohash += str(int(countsize(p + '.wav')))
+    dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene, shot)
+    for p in dubfiles:
+        audiohash += str(int(countsize(p)))
+    print('Audiohash of scene is: ' + audiohash)
+    try:
+        with open(scenedir + '.audiohash', 'r') as f:
+            oldaudiohash = f.readline().strip()
+        print('oldaudiohash is: ' + oldaudiohash)
+    except:
+        print('no audiohash found, making one...')
+        with open(scenedir + '.audiohash', 'w') as f:
+            f.write(audiohash)
+    if audiohash != oldaudiohash or newmix == True or renderfix == True:
+        renderaudio(filmfiles, renderfilename, dubfiles, dubmix)
+        print('updating audiohash...')
+        with open(scenedir + '.audiohash', 'w') as f:
+            f.write(audiohash)
+        for i in range(len(dubfiles)):
+            os.system('cp ' + scenedir + '/dub/.settings' + str(i + 1).zfill(3) + ' ' + scenedir + '/dub/.rendered' + str(i + 1).zfill(3))
+        print('Audio rendered!')
+        newaudiomix = True
+    else:
+        print('Already rendered!')
+    return renderfilename, newaudiomix
+
+
 #-------------Render Scene-------------
 
 def renderscene(filmfolder, filmname, scene):
@@ -1893,7 +1993,6 @@ def renderscene(filmfolder, filmname, scene):
     filmfiles = shotfiles(filmfolder, filmname, scene)
     renderfilename = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/scene'
     scenedir = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/'
-
     # Check if video corrupt
     renderfix = False
     try:
@@ -1907,7 +2006,6 @@ def renderscene(filmfolder, filmname, scene):
         # For backwards compatibility remove old rendered scene files
         run_command('rm ' + renderfilename + '*')
         renderfix = True
-
     # Video Hash
     for p in filmfiles:
         compileshot(p)
@@ -1935,7 +2033,7 @@ def renderscene(filmfolder, filmname, scene):
     newaudiomix = False
     for p in filmfiles:
         audiohash += str(int(countsize(p + '.wav')))
-    dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene)
+    dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene, 0)
     for p in dubfiles:
         audiohash += str(int(countsize(p)))
     print('Audiohash of scene is: ' + audiohash)
@@ -1965,6 +2063,8 @@ def renderscene(filmfolder, filmname, scene):
 def renderfilm(filmfolder, filmname, comp, scene, muxing):
     def render(q, filmfolder, filmname, comp, scene):
         newaudiomix = False
+        if comp == 1:
+            newaudiomix = True
         #This function checks and calls renderscene first then rendervideo & renderaudio if something has changed in the film
         if scene > 0:
             scenefilename, audiomix = renderscene(filmfolder, filmname, scene)
@@ -2007,7 +2107,7 @@ def renderfilm(filmfolder, filmname, comp, scene, muxing):
         for p in filmfiles:
             print(p)
             audiohash += str(int(countsize(p + '.wav')))
-        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, '')
+        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, 0, 0)
         for p in dubfiles:
             audiohash += str(int(countsize(p)))
         print('Audiohash of film is: ' + audiohash)
@@ -2089,14 +2189,16 @@ def renderfilm(filmfolder, filmname, comp, scene, muxing):
 
 #-------------Get dub files-----------
 
-def getdubs(filmfolder, filmname, scene):
+def getdubs(filmfolder, filmname, scene, shot):
     #search for dub files
     print('getting scene dubs')
     dubfiles = []
     dubmix = []
     rerender = False
-    if scene:
+    if scene > 0 and shot == 0:
         filefolder = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/dub/'
+    elif scene > 0 and shot > 0:
+        filefolder = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/shot' + str(shot).zfill(3) + '/dub/'
     else:
         filefolder = filmfolder + filmname + '/dub/'
     try:
@@ -2197,7 +2299,7 @@ def removedub(dubfolder, dubnr):
 
 #-------------Clip settings---------------
 
-def clipsettings(filmfolder, filmname, scene, plughw):
+def clipsettings(filmfolder, filmname, scene, shot, plughw):
     vumetermessage('press record, view or retake to be dubbing')
     pressed = ''
     buttonpressed = ''
@@ -2207,14 +2309,18 @@ def clipsettings(filmfolder, filmname, scene, plughw):
     dubfiles = []
     dubmix = []
     dubmix_old = []
-    if scene:
+    if scene > 0 and shot == 0:
         header = 'Scene ' + str(scene) + ' dubbing settings'
         filefolder = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/dub/'
-        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene)
+        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene, 0)
+    elif scene > 0 and shot > 0:
+        header = 'Scene ' + str(scene) + ' shot ' + str(shot) + ' dubbing settings'
+        filefolder = filmfolder + filmname + '/scene' + str(scene).zfill(3) + '/shot' + str(shot).zfill(3) + '/dub/'
+        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene, shot)
     else:
         header = 'Film ' + filmname + ' dubbing settings'
         filefolder = filmfolder + filmname + '/dub/'
-        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, '')
+        dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, 0, 0)
     newdub = [1.0, 1.0, 0.1, 0.1]
     dubselected = len(dubfiles) - 1
     dubrecord = ''
@@ -2271,7 +2377,7 @@ def clipsettings(filmfolder, filmname, scene, plughw):
                 dubselected = dubselected - 1
         elif pressed == 'remove' and selected == 4:
             removedub(filefolder, dubselected + 1)
-            dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene)
+            dubfiles, dubmix, newmix = getdubs(filmfolder, filmname, scene, shot)
             dubselected = len(dubfiles) - 1
             if len(dubfiles) == 0:
                 selected = 0
@@ -2309,7 +2415,7 @@ def clipsettings(filmfolder, filmname, scene, plughw):
             break
         elif pressed == 'view': # mix dub and listen
             run_command('pkill aplay')
-            dubfiles, dubmix, rerender = getdubs(filmfolder, filmname, scene)
+            dubfiles, dubmix, rerender = getdubs(filmfolder, filmname, scene, shot)
             if scene:
                 filename = filmfolder + filmname + '/scene' + str(scene).zfill(3) +'/scene'
             else:
@@ -3030,7 +3136,7 @@ def stopinterface(camera):
     os.system('pkill tarinagui')
     run_command('sudo systemctl stop apache2')
 
-def startcamera(lens):
+def startcamera(lens, fps):
     camera = picamera.PiCamera()
     camera.resolution = (1920, 816) #tested modes 1920x816, 1296x552/578, v2 1640x698, 1640x1232
     #lensshade = ''
@@ -3058,7 +3164,7 @@ def startcamera(lens):
         if camera_revision == 'rev.D':
             camera.framerate = 23.15
     else:
-        camera.framerate = 24.999
+        camera.framerate = fps
     camera.crop = (0, 0, 1.0, 1.0)
     camera.video_stabilization = True
     camera.led = False