diff --git a/README.md b/README.md index ca7ec4a..be36265 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Frab-Based Into- and Outro-Generator =========================================== -This is a scripted pre-, postroll and pause-clip generator. It takes a Frab/frab schedule-xml and artwork as svg and generates .dv-clips ready-to-use with the [VOC](https://c3voc.de/)-CRS (Continuous Recording System) or any other System. It can aĺso be modified to generate Lossless h264 or something different if reqired. +This is a scripted pre-, postroll and pause-clip generator. It takes a Frab/frab schedule-xml and artwork as svg and generates .dv- or .ts-clips ready-to-use with the [VOC](https://c3voc.de/)-CRS (Conference Recording System) or any other System. It can aĺso be modified to generate Lossless h264 or something different if reqired. Following the requirements of the CRS-Setup it generates one postroll, one pause-sequence and multiple prerolls - one per Talk in your Schedule-xml, but it should be simple to modify this if your Setup needs it. @@ -11,35 +11,35 @@ Okay, let's go. - Install python3, python3-lxml, python3-cssutils, inkscape and libav-tools - Fork this repo on github and clone your personal fork to your local system. - - Copy one of the existing setups (I'd suggest sotmeu14 for a start). - - Open ```artwork/intro.svg``` (preroll template) in inkscape and modify it. You can also just create a new one. For the VOC-Setup you should use a Pixel-Resolution of ```1024x576``` (16:9 Aspect Ratio). + - Copy one of the existing setups (I'd suggest Datengarten `dg` for a start). + - Open `artwork/intro.svg` (preroll template) in inkscape and modify it. You can also just create a new one. For the VOC-Setup you should use a Pixel-Resolution of `1920×1080` (or for the legacy SD/.dv-Pipeline `1024×576`). - Group things together that should be animated together (like subtitle and speaker-text) - Use Flow-Text (in Inkscape drag an Area of Text instead of just placing a single line). This way the text will automatically wrap inside the specified area if it gets too long. - Type Placeholder-Texts where the script should substitute content from your schedule.xml. By default the following placeholders are substituted - - ```$id``` - Talk-ID (useful in links to the Frab-Page) - - ```$title``` - Title of the Talk - - ```$subtitle``` - You guessed it... - - ```$personnames``` - Comma-Separated list of Speaker-Names + - `$id` - Talk-ID (useful in links to the Frab-Page) + - `$title` - Title of the Talk + - `$subtitle` - You guessed it... + - `$personnames` - Comma-Separated list of Speaker-Names - Give IDs to the Objects and Groups you want to animate (Inkscape Shift-Ctrl-O) - Edit your copy of __init__.py - this is your project configuration - - set ```scheduleUrl``` to the url of your schedule.xml-file + - set `scheduleUrl` to the url of your schedule.xml-file - modify introFrames (preroll) - see section about the frame-generators below - - search for ```def debug()``` and comment the sections about outro (postroll) and pause - - run ```./make.py yourproject/ --debug``` to generate your first intro + - search for `def debug()` and comment the sections about outro (postroll) and pause + - run `./make.py yourproject/ --debug` to generate your first intro - if it looks good, duplicate intro.svg to outro.svg (postroll) and pause.svg (pause-loop) and modify them according to your needs. You can use different IDs in your SVG if required - - modify outroFrames and pauseFrames like before an test them using ```./make.py yourproject/ --debug``` - - if everything look like you'd want them to, run ```./make.py yourproject/```. + - modify outroFrames and pauseFrames like before an test them using `./make.py yourproject/ --debug` + - if everything look like you'd want them to, run `./make.py yourproject/`. - You can use any debianesque linux (can be headless) to generate the videos. More cores help more. - - Run ```./make-snapshots.sh yourproject/``` to generate a png from a specific time-index of your .dv-files. You can run ```./make-snapshots.sh yourproject/ 5``` to get a png for the frame at the 5th second of all your dvs. Default is 3 seconds. + - Run `./make-snapshots.sh yourproject/` to generate a png from a specific time-index of your .ts or .dv-files. You can run `./make-snapshots.sh yourproject/ 5` to get a png for the frame at the 5th second of all your clips. Default is 3 seconds. - Viewing through those pngs to check if all intros are looking good with the real-world titles- and person-names - - Viewing through the pngs is faster then opening each .dv and waiting 5 seconds. + - Viewing through the pngs is faster then opening each clip and waiting 5 seconds. The Frame-Generators -------------------- The animation sequence is controlled by the three frame-generator routines vorspanFrames, abspannFrames and pauseFrames. Each of them yields one tupel per frame. This Frame-Tupel contains one Sub-Tupel per Animated Element, which has one of two forms: ### CSS-Style-Modifications -```('logo', 'style', 'opacity', 1),``` - locate object with id ```logo``` in the svg, parse its ```style```-attribute as css-inline-string and change the value of the css-property ```opacity``` to 1. The Tupel-Element ```'style'``` is fixed and declares the type of action which is applied to the specified element. All other tupel-mebers can be modified to suit your needs. +`('logo', 'style', 'opacity', 1),` - locate object with id `logo` in the svg, parse its `style`-attribute as css-inline-string and change the value of the css-property `opacity` to 1. The Tupel-Element `'style'` is fixed and declares the type of action which is applied to the specified element. All other tupel-mebers can be modified to suit your needs. To form an fade-in-opacity-animation, the frame-generator could look like this: @@ -50,7 +50,7 @@ To form an fade-in-opacity-animation, the frame-generator could look like this: ('logo', 'style', 'opacity', "%.4f" % easeInCubic(i, 0, 1, frames)), ) -```easeInCubic``` is an easing-function stolen from the [jquery-easing plugin](http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js) ([easing-cheat-sheet](http://easings.net/)). They take 4 parameters: +`easeInCubic` is an easing-function stolen from the [jquery-easing plugin](http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js) ([easing-cheat-sheet](http://easings.net/)). They take 4 parameters: - t: current time - b: beginning value - c: change In value @@ -68,7 +68,7 @@ So to fade the logo out, the generator yould look like this: By yielding multiple sub-tuples, you can animate multiple elements at the same time using different easings. Its up to you to find a combination that looks nice with your artwork. ### XML-Attribute-Modifications -The other form a sub-tuble can have is ```('box', 'attr', 'transform', 'translate(0,0)')``` - locate object with id ```box``` in the svg, and set its ```transform```-attribute to ```translate(0,0)```. This can be used to animate things not specifiable by css - like the spacial translation of an object. A suitable generator, that animates the element ```box``` in an upward movement, could look like this: +The other form a sub-tuble can have is `('box', 'attr', 'transform', 'translate(0,0)')` - locate object with id `box` in the svg, and set its `transform`-attribute to `translate(0,0)`. This can be used to animate things not specifiable by css - like the spacial translation of an object. A suitable generator, that animates the element `box` in an upward movement, could look like this: # three seconds of animation frames = 3*fps @@ -80,18 +80,18 @@ The other form a sub-tuble can have is ```('box', 'attr', 'transform', 'tr FEM/VOC-Tracker-Integration --------------------------- *that script-Z-thingy* -The [FEM](http://fem.tu-ilmenau.de/) and the [VOC](https://c3voc.de/) uses a special Ticket-Tracker to keep track of the Talks on an event. Various tasks are performed around the recorded Videomaterial (preparing, cutting, encoding, releasing) - synchronized by the Tracker. The files starting with ```script-Z``` are experiments to integrate the intro-rendering into this process. On some Events the Schedule is very fluid with talks being addes or names changing over the whole conference. Using the Scripts to render the prerols when they are actually needed (and not some days before the conference) would help to get the always-freshest prerolls but it would an additional (computational intense) task to the publishing process. +The [FEM](http://fem.tu-ilmenau.de/) and the [VOC](https://c3voc.de/) uses a special Ticket-Tracker to keep track of the Talks on an event. Various tasks are performed around the recorded Videomaterial (preparing, cutting, encoding, releasing) - synchronized by the Tracker. The files starting with `script-Z` are experiments to integrate the intro-rendering into this process. On some Events the Schedule is very fluid with talks being addes or names changing over the whole conference. Using the Scripts to render the prerols when they are actually needed (and not some days before the conference) would help to get the always-freshest prerolls but it would an additional (computational intense) task to the publishing process. Generating an Live-Stream-Overlay --------------------------------- While your working on your Video-Artwork you can create another required asset: the stream overlay. When we'll live-stream your Talks we can't send prerolls ovet the live-stream. To let your viewer now what program they are watching at, we usually overlay a transparent image over the live-stream like most television programs do, too. -Just create another SVG of the size 1024x576 and throw your logo into your prefered corner. To have it looking good we would suggest +Just create another SVG of the size 1920×1080 (or 1024×576 if you're only targeting the legacy SD-Pipeline) and throw your logo into your prefered corner. To have it looking good we would suggest - to test it on dark as well as bright background and add a glow or a backround-box if neccessary - avoid thin lines or small text that will not be visible in the final size - set an opacity of 0.8 to 1.0 (below 0.8 it usually won't be recognizable on a bumpy background) -Save your file as ```artwork/overlay.svg``` +Save your file as `artwork/overlay.svg` -When you're done, call ```./make-overlay.sh yourproject/``` which will generate two .pngs in your artwork directory. One of them looks squeezed - don't worry, that is correct. +When you're done, call `./make-overlay.sh yourproject/` which will generate three .pngs in your artwork directory. One of them looks squeezed - don't worry, that is correct. It works! It doesn't work! -------------------------- diff --git a/emf2016/.DS_Store b/emf2016/.DS_Store new file mode 100644 index 0000000..e110bfb Binary files /dev/null and b/emf2016/.DS_Store differ diff --git a/emf2016/__init__.py b/emf2016/__init__.py new file mode 100644 index 0000000..cda51e3 --- /dev/null +++ b/emf2016/__init__.py @@ -0,0 +1,110 @@ +#!/usr/bin/python3 + +from renderlib import * +from easing import * + +# URL to Schedule-XML +scheduleUrl = 'https://www.emfcamp.org/schedule.frab' + +titlemap = {} + +def introFrames(p): + move=50 + + nr = p['$id']; + + + # Show Title + frames = 5*fps + for i in range(0, frames): + yield ( + ('sponsors', 'style', 'opacity', 0), + ('white', 'style', 'opacity', 0), + ) + + # Fade In Sponsor + frames = int(fps/2) + for i in range(0, frames): + yield ( + ('white', 'style', 'opacity', easeLinear(i, 0, 1, frames)), + ('sponsors', 'style', 'opacity', 0), + ('text', 'style', 'opacity', easeLinear(i, 1, 0, frames)), + ('bg', 'style', 'opacity', easeLinear(i, 1, 0, frames)), + ) + + frames = int(fps/2) + for i in range(0, frames): + yield ( + ('white', 'style', 'opacity', 1), + ('sponsors', 'style', 'opacity', easeLinear(i, 0, 1, frames)), + ('text', 'style', 'opacity', 0), + ('bg', 'style', 'opacity',0), + ) + + # Show Sponsor + frames = 5*fps + for i in range(0, frames): + yield ( + ('white', 'style', 'opacity', 1), + ('sponsors', 'style', 'opacity', 1), + ('text', 'style', 'visibility', 0), + ('bg', 'style', 'visibility', 0), + ) + + + +def outroFrames(p): + # hold slide for 5s + frames = 5*fps + for i in range(0, frames): + yield ( + ) + +def pauseFrames(p): + # hold slide for 5s + frames = 5*fps + for i in range(0, frames): + yield ( + ) + +def debug(): + render( + 'intro.svg', + '../intro.ts', + introFrames, + { + '$id': 69, + '$title': 'How To Make "Your Mum" Jokes Successfully', + '$subtitle': 'But not necessarily tastefully', + '$personnames': 'Matt Gray' + } + ) + + render( + 'outro.svg', + '../outro.ts', + outroFrames + ) + + render( + 'pause.svg', + '../pause.ts', + pauseFrames + ) + +def tasks(queue, args): + # iterate over all events extracted from the schedule xml-export + for event in events(scheduleUrl, titlemap): + + # generate a task description and put them into the queue + queue.put(Rendertask( + infile = 'intro.svg', + outfile = str(event['id'])+".ts", + sequence = introFrames, + parameters = { + '$id': event['id'], + '$title': event['title'], + '$subtitle': event['subtitle'], + '$personnames': event['personnames'] + } + )) diff --git a/emf2016/artwork/.DS_Store b/emf2016/artwork/.DS_Store new file mode 100644 index 0000000..fbd0f94 Binary files /dev/null and b/emf2016/artwork/.DS_Store differ diff --git a/emf2016/artwork/ElectromagneticField2016-Logos-13-crop.png b/emf2016/artwork/ElectromagneticField2016-Logos-13-crop.png new file mode 100644 index 0000000..cdb8b42 Binary files /dev/null and b/emf2016/artwork/ElectromagneticField2016-Logos-13-crop.png differ diff --git a/emf2016/artwork/Logo-OnBackgroundImage.jpg b/emf2016/artwork/Logo-OnBackgroundImage.jpg new file mode 100644 index 0000000..1bf4788 Binary files /dev/null and b/emf2016/artwork/Logo-OnBackgroundImage.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/.DS_Store b/emf2016/artwork/Sponsor Logos/.DS_Store new file mode 100644 index 0000000..de531a7 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/.DS_Store differ diff --git "a/emf2016/artwork/Sponsor Logos/1 Gold/Icon\r" "b/emf2016/artwork/Sponsor Logos/1 Gold/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/emf2016/artwork/Sponsor Logos/1 Gold/mathworks.jpg b/emf2016/artwork/Sponsor Logos/1 Gold/mathworks.jpg new file mode 100644 index 0000000..749142a Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/1 Gold/mathworks.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/1 Gold/microsoft.jpg b/emf2016/artwork/Sponsor Logos/1 Gold/microsoft.jpg new file mode 100644 index 0000000..729d0e1 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/1 Gold/microsoft.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/1 Gold/nexmo.png b/emf2016/artwork/Sponsor Logos/1 Gold/nexmo.png new file mode 100644 index 0000000..5514876 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/1 Gold/nexmo.png differ diff --git a/emf2016/artwork/Sponsor Logos/1 Gold/spotify.png b/emf2016/artwork/Sponsor Logos/1 Gold/spotify.png new file mode 100644 index 0000000..3542e5e Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/1 Gold/spotify.png differ diff --git a/emf2016/artwork/Sponsor Logos/1 Gold/ucl.png b/emf2016/artwork/Sponsor Logos/1 Gold/ucl.png new file mode 100644 index 0000000..3c1e0c9 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/1 Gold/ucl.png differ diff --git "a/emf2016/artwork/Sponsor Logos/2 Badge/Icon\r" "b/emf2016/artwork/Sponsor Logos/2 Badge/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/emf2016/artwork/Sponsor Logos/2 Badge/getsmarterenergy.png b/emf2016/artwork/Sponsor Logos/2 Badge/getsmarterenergy.png new file mode 100644 index 0000000..b3c4a52 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/2 Badge/getsmarterenergy.png differ diff --git a/emf2016/artwork/Sponsor Logos/2 Badge/hcd.jpg b/emf2016/artwork/Sponsor Logos/2 Badge/hcd.jpg new file mode 100644 index 0000000..59b873d Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/2 Badge/hcd.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/2 Badge/rs.png b/emf2016/artwork/Sponsor Logos/2 Badge/rs.png new file mode 100644 index 0000000..8084b35 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/2 Badge/rs.png differ diff --git a/emf2016/artwork/Sponsor Logos/2 Badge/st.png b/emf2016/artwork/Sponsor Logos/2 Badge/st.png new file mode 100644 index 0000000..a4a73da Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/2 Badge/st.png differ diff --git a/emf2016/artwork/Sponsor Logos/2 Badge/ti.png b/emf2016/artwork/Sponsor Logos/2 Badge/ti.png new file mode 100644 index 0000000..82e0592 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/2 Badge/ti.png differ diff --git a/emf2016/artwork/Sponsor Logos/2 Badge/wurth.jpg b/emf2016/artwork/Sponsor Logos/2 Badge/wurth.jpg new file mode 100644 index 0000000..c8bd298 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/2 Badge/wurth.jpg differ diff --git "a/emf2016/artwork/Sponsor Logos/3 Silver/Icon\r" "b/emf2016/artwork/Sponsor Logos/3 Silver/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/emf2016/artwork/Sponsor Logos/3 Silver/heartinternet.png b/emf2016/artwork/Sponsor Logos/3 Silver/heartinternet.png new file mode 100644 index 0000000..4c56459 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/3 Silver/heartinternet.png differ diff --git a/emf2016/artwork/Sponsor Logos/3 Silver/portcullis.jpg b/emf2016/artwork/Sponsor Logos/3 Silver/portcullis.jpg new file mode 100644 index 0000000..fb36cad Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/3 Silver/portcullis.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/3 Silver/yelp.png b/emf2016/artwork/Sponsor Logos/3 Silver/yelp.png new file mode 100644 index 0000000..64314dd Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/3 Silver/yelp.png differ diff --git "a/emf2016/artwork/Sponsor Logos/4 Bronze/Icon\r" "b/emf2016/artwork/Sponsor Logos/4 Bronze/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/chef.png b/emf2016/artwork/Sponsor Logos/4 Bronze/chef.png new file mode 100644 index 0000000..dbb6389 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/chef.png differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/codethink.png b/emf2016/artwork/Sponsor Logos/4 Bronze/codethink.png new file mode 100644 index 0000000..e1dd497 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/codethink.png differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/dhtmlx.jpg b/emf2016/artwork/Sponsor Logos/4 Bronze/dhtmlx.jpg new file mode 100644 index 0000000..8b13fdd Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/dhtmlx.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/flexoptix.jpg b/emf2016/artwork/Sponsor Logos/4 Bronze/flexoptix.jpg new file mode 100644 index 0000000..1829418 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/flexoptix.jpg differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/improbable.png b/emf2016/artwork/Sponsor Logos/4 Bronze/improbable.png new file mode 100644 index 0000000..f9c4bda Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/improbable.png differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/justaddsharks.png b/emf2016/artwork/Sponsor Logos/4 Bronze/justaddsharks.png new file mode 100644 index 0000000..22757c1 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/justaddsharks.png differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/medicalconnections.png b/emf2016/artwork/Sponsor Logos/4 Bronze/medicalconnections.png new file mode 100644 index 0000000..9ddf989 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/medicalconnections.png differ diff --git a/emf2016/artwork/Sponsor Logos/4 Bronze/twilio.png b/emf2016/artwork/Sponsor Logos/4 Bronze/twilio.png new file mode 100644 index 0000000..48d1517 Binary files /dev/null and b/emf2016/artwork/Sponsor Logos/4 Bronze/twilio.png differ diff --git a/emf2016/artwork/intro.svg b/emf2016/artwork/intro.svg new file mode 100644 index 0000000..46bf4ad --- /dev/null +++ b/emf2016/artwork/intro.svg @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + $title$subtitle$personnames + + + + + + + Sponsored By + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emf2016/artwork/outro.svg b/emf2016/artwork/outro.svg new file mode 100644 index 0000000..fd3ced5 --- /dev/null +++ b/emf2016/artwork/outro.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/emf2016/artwork/pause.svg b/emf2016/artwork/pause.svg new file mode 100644 index 0000000..fd3ced5 --- /dev/null +++ b/emf2016/artwork/pause.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/make-overlay.sh b/make-overlay.sh index 9dd1537..fbb9bd6 100755 --- a/make-overlay.sh +++ b/make-overlay.sh @@ -4,6 +4,7 @@ if ! pushd "$1/artwork/" >/dev/null 2>&1; then exit 1 fi +inkscape --export-width=1920 --export-height=1080 --export-png=overlay-1920x1080.png overlay.svg inkscape --export-width=1024 --export-height=576 --export-png=overlay-1024x576.png overlay.svg inkscape --export-width=720 --export-height=576 --export-png=overlay-720x576.png overlay.svg diff --git a/renderlib.py b/renderlib.py index 2877c98..b71c04d 100644 --- a/renderlib.py +++ b/renderlib.py @@ -129,7 +129,7 @@ def rendertask(task): fp.write( etree.tostring(svg, encoding='unicode') ) # invoke inkscape to convert the generated svg-file into a png inside the .frames-directory - errorReturn = subprocess.check_output('cd {0} && inkscape --export-background=white --export-png=.frames/{1:04d}.png .gen.svg 2>&1 >/dev/null'.format(task.workdir, frameNr), shell=True, universal_newlines=True) + errorReturn = subprocess.check_output('cd {0} && inkscape --export-background=white --export-png=$(pwd)/.frames/{1:04d}.png $(pwd)/.gen.svg 2>&1 >/dev/null'.format(task.workdir, frameNr), shell=True, universal_newlines=True) if errorReturn != '': print("inkscape exitted with error\n"+errorReturn) sys.exit(42)