Avtomatizacija powerpoint to mp4 video

V enem prejšnjih postov sem opisal, kako se ročno izvede konverzija powerpointa v obliko primerno za predvajanje na TVju. Kot sem že omenil, imam teh datotek kar precej, in konverzija posamezne traja na mojem iMacu, kjer laufam powerpoint znotraj vmware virtualne mašine, od 20 do 40 minut. Kar vse skupaj pomeni več dnevno delo. Zato je avtomatizacija pač nujna. Sicer smo tehnični ljudje že te sorte, da si radi avtomatiziramo tudi enkratna opravila, kar je pa vsaj ponavadi precej kontraproduktivno. Vsaj časovno gledano. Ker iz stališča zabave, učenja in negovanja tehnične dediščine je to zelo produktivno.

[youtube CIcjxlssiHY]

Zamislil sem si nekako takole. V powerpintu spišem macro, ki obdela vse powerpointe in jih shrani v pptx obliko, ter exportira kot video v vmw obliko. Nato pa to vse skupaj obdelam še z bash skripto v MAC OSX okolju. Načeloma bi vse skupaj lahko naredil tudi znotrej powerpoint macroja, ker tudi tam lahko pač kličem potrebne zunanje programe (unzip, ffmpeg) ampak nekako mi je unix scripting precej bližje, pa še izvajalo se bo direkt na mašini in ne v virtualnem okolju. VBscript, ki se uporablja za macro je pa itak ena čista veselica. No, ampak smo preživeli.

Lahko bi šel pisati tudi v C# in opri tem uporabljal powerpointove objekte, ampak ker nimam postavljenega razvojnega okolja za C# z office dodatki, bi mi še to verjento vzelo par ur.

Kako izgleda skripta v powerpointu:

Option Explicit
Sub PrepareWMVandPPTX()
   Dim FSO, FLD, FIL, objpp, prsPres
   Dim strFolder
   Dim n
   Set objpp = CreateObject("Powerpoint.application")
   strFolder = "C:\pathtoppsfiles"
   Set FSO = CreateObject("Scripting.FileSystemObject")
   Set FLD = FSO.GetFolder(strFolder)
   n = 0
   For Each FIL In FLD.Files
      If n > 10 Then Exit For
      If (FSO.GetExtensionName(FIL.Name) = "pps") And ((Not FSO.FileExists(strFolder & "\" & FSO.GetBaseName(FIL.Name) & ".pptx")) Or (Not FSO.FileExists(strFolder & "\" & FSO.GetBaseName(FIL.Name) & ".wmv"))) Then
         Set prsPres = objpp.Presentations.Open(strFolder & "\" & FIL.Name)
         If Not FSO.FileExists(strFolder & "\" & FSO.GetBaseName(FIL.Name) & ".pptx") Then
            prsPres.Convert2 strFolder & "\" & FSO.GetBaseName(FIL.Name) & ".pptx"
         End If
         If Not FSO.FileExists(strFolder & "\" & FSO.GetBaseName(FIL.Name) & ".wmv") Then
            n = n + 1
            prsPres.CreateVideo strFolder & "\" & FSO.GetBaseName(FIL.Name) & ".wmv", True, 5, 720, 25, 100
         End If
         prsPres.Close
      End If
    Next
End Sub

Simpl ko pasulj. Sprehodimo se čez vse pps datoteke, ki še nimajo ustrezne pptx in/ali wmv datotee. Odpremo prezentacijo, pokličemo konverzijo v pptp in poženemo kreiranja videa. Še najzahtevnejši del je bilo poiskati pomen zadnjega parametra pri kreiranju videa, ki je quality, nikjer pa ni pisalo v kakšnih enotah. Iz enega francoskega primera sem potem razbral da gre za procente.

Tale CreateVideo v bistvu ne naredi exporta, ampak le doda file v čakalno vrsto. Tako da, če poženemo to skripto v direktoriju s 100 prezentacijami, se bo relativno hitro zaključila, nato pa bo powerpoint počasi kreiral videe. No, praksa je pokazala, da če jih ima v vrsti par 10, je precej nagnjen k temu da crkne. Tako da poganjam v etapah po 10 komadov. Ni pa nič narobe, če se makro požene, preden je vse iz vrste že podelal. Tako da mu jih za čez noč pripravim 20 ali 30.

Ok, kot rezultat tega, dobivamo pptx in wmv datoteke. Sedaj se pa preselimo v MAC OSX bash okolje. Tudi tale skriptica ni prav posebej zahtevna:

#!/bin/bash
for file in *.pptx; do
   name="${file%.[^.]*}"
   wavname=$name".wav"
   wmvname=$name".wmv"
   mp4name=$name".mp4"
   wavname2=$name".2.wav"
   wavname3=$name".3.wav"
   echo "$file" - "wmvname" # "$mp4name"
   if [ ! -f "$mp4name" -a -s "$wmvname" ];
      then
         if [ ! -f "$wavname" ];
            then
               unzip -j "$file" "*.wav"
               mv audio1.wav "$wavname"
         fi
         if [ ! -f "$wavname2" ];
            then
               ffmpeg -i "$wavname" "$wavname2"
         fi
         if [ ! -f "$wavname3" ];
            then
               sox "$wavname2" "$wavname3" REPEAT 6
         fi
         if [ -s "$wavname3" -a -s "$wmvname" ];
            then
               ffmpeg -i "$wavname3" -i "$wmvname" -qscale 1 -shortest "$mp4name"
         fi
         rm "$wavname"
         rm "$wavname2"
         rm "$wavname3"
   fi
done

Tokrat se sprehodimo čez vse pptx datoteke, ter si na osnovi imena datoteke pripravimo ostala imena z različnimi končnicami. Nato pa v glavnem se le sprašujemo, ali neko pomožno datoteko že imamo, in če je nimamo jo pač kreiramo. Z unzipom potegnemo wav iz pptx datoteke. Le ta je mp3 enkodiran znotraj wav, česar sox ne razume, zato to najprej z ffmpegom predelamo v normalno wav datoteko. Nato z sox-om zvok pomnožimo (zakaj je opisano v prejšnjem zapisu), in izvedemo končno združevanja videa in zvoka v mp4 video datoteko.

Pri tej skripti je bilo v nasprotju s pričakovanju več težav. NAmreč ffmpeg se nekaj igra z stdio in mi osnovna verzija loopa zaradi tega ni delala. In pa pri nekaterih datotekah ffmpeg enostavno crkne. Oziroma niti ne crkne, ampak se spravi v neskončno zanko. To je v bistvu zaenkrat nerešljivo, ker se pa zgodi na cirka 5% primerov, se zaenkrat niti ne sekiram. Jih bom moral ročno pogledat in morda kakšen aprameter spremeniti, pa bo.

Enhanced by Zemanta