Archive for the 'workflow' Category

Mac workflow: memory dump, avagy mentsük ami menthető

Még kómásan ugyan, de felkeltem már 6 körül dolgozni, tudván, hogy a munkanapnak nálam ma délben vége szakad, feladat pedig van bőven. Első körben egy viszonylag hosszabb elemzés megírását akartam befejezni, amit egy zárt phpBB forumba kell postolnom.

Az első hibát ott követtem el, hogy a pár mondatnál hosszabb anyagot nem egy text editorban kezdtem el legyártani, hanem a fórummotor saját comment textboxában.
Kész lett a bejegyzés, nyomtam egy Preview-t ami legenerálta a bejegyzést végleges formájában, átolvastam, majd miután találtam benne pár apró elírást, egy rutinmozdulattal rányomtam a browser tab close gombjára, hogy folytathassam a szerkesztést. Igen ám, csak a WordPress-hez szokott agyam gondolkodott így a korai órán, dacára a fél liter tejeskávénak: a phpBB ugyanis a WordPress-szel ellentétben a Preview-t ugyanabba a tab-ba generálta le, plusz nem készített róla Draft mentést, így én egy elegáns mozdulattal becsuktam bő fél órányi munkámat.

Mivel ez nem egy post commentje volt, hanem effektív munka, amelyre több kollégám számít, muszáj volt újraírni, de legalábbis előtúrni valahogy. Ilyenkor jön a képbe a lusta coder egyetlen fegyvere, az agya.

Nagy eséllyel az épp bezárt ablak tartalma ott lapul valahol a RAM-ban, így már csak egy memdumpot végző alkalmazás és egy keresni tudó jóféle hex editor kell ahhoz, hogy kikotorjam a postot, ahelyett, hogy újragépelem.

A memdump elvégzéséhez a Mac Memory Reader nevű binárist használtam - egyértelmű kis célszerszám, sokat nem kérdez, csak dumpol és sanyi.
A szöveget fds cimborám által is nagyra tartott Hex Fiend segített előkeresni.

Ettől tovább nem is kell ragozni a történetet. Ha esett meg már veled hasonló baj, szedd most le a Mac Memory Readert, telepítsd fel, hogy amikor legközelebb ér ilyen baleset, minél kevésbé koszold be a dumpolandó memóriát.

Mac workflow: a supporter fegyvere az embeddelő userek ellen

A probléma

A gonosz user küld nekünk egy hibaüzenet screenshotot, jó esetben csak egy, rosszabb esetben több, általában Office dokumentumban egymásba ágyazva (jött már olyan, hogy a szép fejléces (!) PowerPointba ágyazott debug screenshot csini Word dokumentumba gyógyítva, szép veretes picture frame-mel). Megkapom, ránézek és máris nem kell lemennem evezni, hogy 150-re szökjön a pulzus:

user-embeddelt-hibauzenete

A megoldás

Azért jó ideje már nem szökik. Egyfelől van nekem szép \screenshot fedőnevű TextExpander shortcutom, ami ilyet csinál azonnal a válaszmailbe:

Képernyőfotók küldése Windows alatt a legegyszerűbb módon
 
1. Tegyük aktívvá a fotózandó ablakot (egyszerűen rá kell csak kattintani).
2. Nyomjuk meg az Alt+Print Screen billentyűkombinációt — a fotó az aktív ablakról a vágólapra kerül.
3. Indítsuk el a levelező programunkat, kezdjünk el egy új levelet.
4. Kattintsunk a levél törzsébe, és oda illesszük be a vágólap tartalmát a Control+V billentyűkombinációval.
5. Címezzük meg a levelet és küldjük el!

Másrészt nem lennék címzetes shareware junkie lovag, ha ne tartanék erre fent egy appot. Az app neve File Juicer. A kis 13 EUR-ba kerülő shareware alkalmazás az univerzális kicsomagoló - rengetegszer behozta már az árát nekem. Számos formátumot képes atomjaira szedni, továbbá nagy segítség tud lenni, ha memóriakártyáról kell visszahozni törölt adatot.

A File Juicer kis ronda ikonnal rendelkezik, valamint az UI sem egy díjnyertes csődör:

file-juicer-UI

Az ablak bal oldalán található drop target boxba, vagy az alkalmazás dokkon levő ikonjára kell dobnod a gonosz felhasználó által küldött dokumentumot, amit az app szétszed, ahogy illik:

file-juicer-result

A File Juicer természetesen AppleScriptelhető, így semeddig nem tart egy Service-t gyártani hozzá, ami jobb clickre indítja a konverziót. Minden embeddelő userellenséggel találkozó Mac OS X usernek kötelező fegyver ez a kis gyöngyszem.

Update: Józsi párhuzamos postja a témában erre.

Mac workflow: fordító service

Preface: a workflow Google API-t használ, így feltételezem, hogy rendelkezel a használatához szükséges Google accounttal, továbbá Growl felhasználó vagy. Ha nincs Google accountod és nem is akarsz gyártani magadnak, illetve a Growl-tól is kiver a víz, akkor ez a leírás számodra nem nyújt explicit megoldást.

Update: fds Mester hatására kigyomláltam a gusztustalan urlencode függvényt és az amúgyis nagyon okos curl binárisra róttam ezt a terhet.

A probléma

Idegen szóval / kifejezéssel találkozunk a computeren olvasás közben, amire a gyári Dictionary.app-ba integrált szótárunk nem ad fordítást.

A megoldás

Van a Google-nek jóféle online translation API-ja, amit megkérhetünk szépen, hogy fordítson nekünk. Az OS X nagy varázslata a rendszer szintű AppleScript támogatás és az Automator fedőnevű makrózó csoda - őket szólítjuk most csatába.

Első körben ellátogatunk a Google Translate API oldalára és végigolvassuk a doksit. A dokumentáció szépen elmagyarázza, hogy Google-ék egy ilyen GET requestre adnak értelmes választ:

https://www.googleapis.com/language/translate/v2?parameters

A HTTPS request felparaméterezve így néz ki:

https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&q=hello%20world&source=en&target=hu

Miután ezt megtudtuk, a doksiban leírtak szerint látogassunk el a Google APIs Console oldalra, készítsünk egy új Translate projectet és már meg is szereztük a Translate API híváshoz szükséges kulcsot.

Megvan a kulcs, csinálhatunk jó kis Service-et!
Elindítod az Automator alkalmazást, majd kiválasztod a Service típusú template-et:

A megjelenő editorban a Library/Utilities szekcióból kikeresed a Run AppleScript actiont és behúzod a munkaterületre:

Ezután már csak bepakolod a script helyére azt, amint én hajnalban már kiszenvedtem, beteszed a set myKey to "PUT_YOUR_GOOGLE_API_KEY_HERE" sorba a te saját Google Translate API kulcsod és lemented a file-t Translate néven.

Ha mindent jól csináltál, akkor megjelent egy Translate nevű service a gépeden, ami úgy működik, hogy egy tetszőleges alkalmazásban kijelölt szövegen jobb clicket nyomva, majd a Services menü Translate opcióját kiválasztva a script megküldi a Google Translate APInak a kijelölt szöveget és a visszakapott fordítást megjeleníti neked egy Growl notification buborékban, valahogy így:

Végül nézzük meg a scriptet egyben, úgy, ahogy magamnak implementáltam:

(*
	Translate
	by Gabor PENOFF (http://fns.csokolade.hu)
 
	release 20110208_092849
 
	About:
 
 
	Requirements:
	- insert your own Google API key
	- install Growl from http://growl.info to get non-modal notification dialogs
 
	Usage:
	- select some text and run the service
 
	That's all.
*)
 
on run {input, parameters}
 
	set srcText to input as text
 
	set srcLang to "en" -- source language
	set tgtLang to "hu" -- target language
	set myKey to "AIzaSyCI-2oapEkMpRFfd6Ltv4HkZhf1Zq-VU9o"
	set myScriptID to "Translate" -- ID for Growl display
 
	set myTranslation to do shell script "/usr/bin/curl -G --data-urlencode q=" & quoted form of srcText & " --data-urlencode key=" & quoted form of myKey & " --data-urlencode source=" & quoted form of srcLang & " --data-urlencode target=" & quoted form of tgtLang & space & quoted form of "https://www.googleapis.com/language/translate/v2"
 
	if myTranslation = "" then
		tell me to notifyWithGrowl(myScriptID, "ERROR")
		return
	end if
 
	-- get rid of JSON (ugly but works)
	set myPrefix to "translatedText\": \""
	set myPostfix to "\""
	set myStartPos to (offset of myPrefix in myTranslation) + (length of myPrefix)
	set myText to text myStartPos thru -1 of myTranslation
	set myEndPos to (offset of myPostfix in myText)
	set myText to text 1 thru (myEndPos - 1) of myText
 
	tell me to notifyWithGrowl(myScriptID, myText)
 
	return "" -- myText
end run
 
-- GrowlCheck:
on growlInstalled()
	try
		do shell script "ls /Library/PreferencePanes/Growl.prefPane/"
		return true
	on error
		return false
	end try
end growlInstalled
 
-- Growl notifier:
on notifyWithGrowl(myApp, myText)
	set myIconApp to "Safari"
	set notificationID to myApp & ".default"
 
	if growlInstalled() then
		tell application "GrowlHelperApp"
			-- list of notification types
			set the ANL to {notificationID}
			-- list of enabled notifications
			set the DNL to {notificationID}
 
			-- register script
			register as application myApp all notifications ANL default notifications DNL icon of application myIconApp
			-- send notification
			notify with name notificationID title myApp description myText application name myApp
		end tell
	else
		-- skip alert if no Growl installed
		--display alert "Growl is not installed"
	end if
end notifyWithGrowl

Türelmetleneknek / elfoglaltaknak / lustáknak az egész service szedhető innen - persze még ebben is be kell pakolnod a saját magad Google API kulcsát, hogy működjön.

Mac workflow: válogassunk video nyersanyagot

Preface: ezt a postot ma délután egy agyatlan flame-mel támadó kolegám indukálta, aki csak a gonoszt látta mindenben, ami harapott almás, incl. az általam használt computer és annak operációs rendszere. Jómagam azt vallom, hogy feladathoz kell választani az eszközt: épületet nem akarunk mindenáron Silicon Graphics mainfarme-ekkel vezérelni, mikor egy 5 Wattos kis ARM masina is elviszi, viszont 3D-t biztos azon renderelnék legnagyobb örömmel.
Hogy az eszközt a feladathoz teóriát demonstráljam, elengedtem a 3rd party tooljaimat és megszültem ezt a workflowt.

Tegyük a $SUBJECT-et a vanilla óperenciás rendszer segítségével - semmi extra alkalmazás!

  • Legyen egy folderünk, tele videós nyersanyaggal, amit nyissunk meg Finderben.
  • Nyomjunk egy ⌘1 kombinációt a billentyűzeten, hogy a Finder ablakunk ikon nézetet mutasson.
  • Klikkeljünk a Finder ablak jobb felső sarkában tanyázó kis gombra, ami eltünteti a Finder sidebart és a toolbart is, valamint átköltözteti a Finder ablak aljáról a statusbart és a zoom slidert az ablak tetejére, maximális helyet hagyva nekünk a nézelődéshez:

Finder-with-sidebar

Finder-without-sidebar

  • Állítsuk a Finder ablakot böszme méretűre, majd húzzuk odáig a zoom slidert, hogy már élvezhető méretű thumbnaileket kapjunk a nyers videókból:

Finder-zoom-slider

  • Húzzuk az egérkurzort egy videó fölé, majd klikkeljünk a közepén megjelenő ikonra, hogy elinduljon a kívánt méretűre állított thumbnailben (!) a lejátszás:

Finder-video-play-icon

  • Ha a thumbnail kicsi, csak jelöljük ki a videófile-t és nyomjunk egy SPACE-t az ablakos lejátszáshoz, vagy egy ⌥SPACE-t a fullscreen-en történő lejátszáshoz:

quick-look-video-play

Végül az emlegetett stock Finder ablak az alábbi képre klikkolva rendes méretben:

Mac workflow: worklog generator

Preface: a mai workflow mese nem annyira strict OS X dolog, pusztán egy mezei Bash shell scriptet írunk meg benne.

Hónap eleje van - ilyenkor számlázok és írom a worklogot - ez utóbbiról lesz most szó. eFi munkája software support munka: többek között fejlesztek új toolokat és karbantartom a régieket, zömmel VBA-ban. A Microsoft Office VBA nem haszontalan stuff, ám több szempontból is szörnyűséges egy szerzet - elég csak arra gondolni, hogy az Office dokumentumba írt kódot (WTF?) csak egyesével, ún. modulonként tudod kézzel plain text file-ba menteni, az IDE semmi ettől extrább támogatást nem ad.
Anno, amikor elkezdtem VBA-val foglalkozni, írtam magamnak olyan környezetet, ami egy klikkre release ID-t generál az adott verziónak, új sort nyit a kódhoz tartozó changelogban és képes az így megjelölt kódfát tokkal-vonóval plain text file-okba egy verzióként kipakolni. Ehhez aztán készlült egy VBA updater motor is, ami ezt a mentést képes volt visszatölteni, de az egy másik történet - maradjunk most a lementett kódfánál, ami changelogostól pihen a HDD-n egy hierarchikus folder struktúrában.

A velem support szerződést kötő cégnek havonta számlázok, a számla mellé pedig logot kell mellékelnem, ami elmagyarázza, hogy a kiszámlázott hónapban milyen munkákat végeztem el. Ennek a lognak az előállítását automatizálja némiképp a worklog script. Nézzük meg, azt a végén elmagyarázom röviden, hogy hogy is megy ez az egész:

#!/bin/sh
SCRIPT=`basename $0`
 
if [ "$#" != "1" ]; then
	echo "$SCRIPT - list changes made within a month"
	echo "Usage: $SCRIPT yyyymm"
	exit 1
fi
 
MYPATH=/Users/fns/Documents/xp/support/_code
PATHLEN=$((${#MYPATH}+1)) #+1 to cut first slash character as well
 
echo "$SCRIPT - list of changes made on $1\n"
for f in $(find $MYPATH -iname "changelog*")
do
if [ -a $f ]; then
	LOG=`cat $f | grep "'$1"`
	if [ "$LOG" != "" ]; then
		SRC=${f:PATHLEN}
		echo "Log from $SRC:"
		echo "$LOG\n"
	fi
fi
done

A script a kódfákat tartalmazó top level folderen elindulva végigszalad és előszedi a subfolderekben lakó changelog file-okat. Ilyen changelog minden kódfában csak egy van és historikusan tartalmazza a forrásban elkövetett változtatások rövid szöveges leírását. Egy sor a changelogban 3 elemből áll:

  • az eleje mindíg a release ID, ami yyyymmdd hh:mm formátumú,
  • a közepe egy byte-nyi flag, ami azt jelöli, hogy az adott módosítás új feature (+), törölt feature (-), bugfix (*), vagy éppen csak hangosan gondolkodok (?),
  • a vége pedig maga a változás szöveges leírása.

Namármost, ha a changelog sorok elején található 'yyyymm kezdetű stringre szűrünk és csak azokat a changelog-okat jelenítjük meg a szűrt tartalommal együtt, amelyek az adott yyyymm patternre illeszkednek, akkor már le is generáltuk a munka leigazolását. Ezek után nincs más hátra, mint a különböző projectek szűrt changelogját a megfelelő kuncsaftnak megküldeni.

Végül itt egy minta a script által gyártott eredményből:

worklog - list of changes made on 201010
 
Log from cpt/modules/ChangeLog.bas:
'20101011 20:00 *   Default report fix (default report created instead of last used one when no SF ARCHIVE present and the last used report wants it).
'20101011 20:46 *   Asset efficiency % report regional fix.
'20101012 12:16 *   Demand cmp Reports disabled when no SF ARCHIVE present.
'20101013 18:57 +   Forced forecast archive generation if user omits it to prevent freezing of forecast archive related reports.
'20101013 20:04 +   Asset group selection support for Demand share per family report.
'20101015 08:20 *   Demand share per family report MSO/FCODE array empty fix.
'20101016 10:41 +   Forecast archive generator hack improved.

Mac workflow: feed reading

Google Readerben laknak az általam olvasott RSS feedek nagyjából 2006 óta, amikor is Sasvári "angelday" Józsi előadta nekem, hogy miért is jó így olvasni. A Google Reader nagy kedvenc: szinte ipari standard és a webes kliense szinte mindent visz. A "szinte" szó használatát nálam egyedül egyetlen feature hiánya indokolja: nincs olyan keyboard shortcut a webes alkalmazásukban, amellyel a feedek átfutása közben az engem érdeklő cikket a böngésző a háttérben nyitná meg ahelyett, hogy a feedreader elé nyitna egy tab-ot (V shortcut).
Szerencsére mind Safari, mind Google Chrome alatt van a problémára megoldás: Safari fanatikusoknak a Zak Johnson által írt greader-bgtabs extensiont, míg a Chrome usernek a Google Reader: Open in background tab kiterjesztést kell felpakolniuk ahhoz, hogy a "V" shortcutra a Google Readerben olvasott aktuális cikk a háttérben nyíljon meg. Valószínűleg Firefoxra is van hasonló hack, de én azt a browsert csak ritkán szedem elő.

A Google Reader webapp valamennyire iOS optimalizált is, ám én kifejezetten utálom az iPad verziót: egyszerűen nem áll kézre. Szerencsére ezen a problémán gyorsan átugraszt a Reeder nevű natív iOS Google Reader frontend, amely iPhone és iPad változatban is külön-külön létezik, 3 és 5 USD pénzért (nem szeretem az extra pénzért különválasztott iOS portokat, de ez van - nemrég a Reeder for iPhone szülinapi akcióban volt fogható 1 USD ellenében, akkor elköltöttem rá gyorsan egy liter tej árát).

A Reeder fantasztikus alkalmazás, bátran mondom, hogy ha még nem ismered, de Google Reader felhasználó vagy, vedd meg vakon és nem fogsz benne csalódni. Korrekt, ergonómikus, intuitív UI, szemet gyönyörködtető design.

Reeder-iPad

A fejlesztő dolgozik már a Mac OS X porton is - a reederapp twitter feedből épp pár napja derült ki, hogy a desktop verzió bétája a madeatgloria.com/brewery oldalon landol hamarosan. Bár nagy szükségét nem érzem egy asztali Google Reader alkalmazásnak, de azért érdeklődve várom, hogy vajon hasonlóan korrekt eszközt sikerül-e faragni, mint amilyen az iOS port.

Mac workflow: vágjunk filmet!

Ma reggel csak egy hirtelen-kisült workflow anyagra van idő, mégis elkészítem, mert két fejfájástól is meg tud menteni, ha hozzám hasonlóan belefutsz az alábbi problémákba.

Video vágáshoz én az Apple Final Cut Express 4 alkalmazását használom. Ugyan az aktuális iLife csomagban ott van az erre készült korrekt kis iMovie, azonban valami miatt még a Mac-es életem elején felhagytam vele (talán nem tudott frame-re pontosan vágni) és maradt a FCE, amit a mai napig nagyon szeretek.

A probléma

Az Apple az utolsó iMovie/Final Cut release után előállt az "open format timeline"-nak nevezett dologgal, ami nagyjából annyit tesz, hogy konvertálás nélkül keverheted a videovágó software-ben a különböző video codec-ű nyersanyagokat, meg fogja emészteni on the fly. Ez így is van, csak éppenséggel precíz munkához a 2008 late harvest MacBook Pro-n használhatatlan a tömörített nyersanyag, úgyhogy video nyersanyagot konvertálni muszáj. A nagytesó Final Cut Studioban erre ott a beépített Compressor alkalmazás és egy fancy Apple ProRes 422 codec, de ez tegyük fel, hogy nekünk most nem áll rendelkezésre és keressünk helyette ingyenes megoldást.

A másik, viszonylag ritkábban jelentkező, éppen azért alattomos kis probléma, mikor az audio sávban használt mp3 "cirpel", pattog, vagy akár 1-1 frame erejéig kihagy, a teljes rendering után is. A ludas ezúttal is a tömörítés, úgyhogy az audio adatunkat is ki kell, hogy csomagoljuk.

A megoldás #1/2: video konvertálása

A mozink konvertálásához a squared5.com által gyártott ingyenes MPEG Streamclip nevű alkalmazást fogjuk használni, melynek OS X és Windows változata is létezik. Advancedebb arcok persze az ultimate ffmpeg appot használják command line varázslattal, de én lustaságból leragadtam a GUI-s toolnál. Mondjuk pont OS X alatt simán lehetne gyártani egy Folder Action scriptet, ami az erre dedikált "konvertáló pool" jellegű folderbe bedobált file-okat nekiáll ffmpeg-gel azonnal kicsomagoltatni... na, talán egy másik workflow postban megcsináljuk.

Az általam termelt video nyersanyag 1920x1080 PAL (=25fps) felbontású, H.264 codec-kel készül a kamera belsejében. A tömörített file-jainkat az MPEG Streamclip az alábbi beállításokkal kóserolja ki szép uncompressed, ám mégis valamennyire tömör formába (=ezt fedi le a beállított Apple Intermediate Codec):

mpeg-streamclip-settings-5dmk2

Az MPEG Streamclip egy kötegben végigcsinálja ezt az összes forrásadatunkkal, plusz a folyamat megállítható, meg még sok egyéb fancy dologra képes, amiket nem részletezünk. Persze egy darab ciklus lenne a kötegelt feldolgozás az ffmpeg-et hívó shell scriptnek is, de hát a lustaság nagy úr...

A megoldás #2/2: audio konvertálása

A zenét Quicktime 7 segítségével konvertáljuk AIFF formátumúra, amit a FCE már gond nélkül fogyaszt:

quicktime-7-export-to-aiff

Ezután más dolgunk már nincs, mint feldolgozni a preparált nyersanyagokat. Have fun!

Mac workflow: Mac-iOS cross notifications

Az eheti Mac workflow részben üzeneteket fogunk közvetíteni az asztali Mac-ünk és a *.iOS device-unk (=jelenleg iPod Touch / iPhone* / iPad) között.

A probléma onnan indul, hogy lusta vagyok begépelni az iOS eszközön egy hosszabb URL-t - nem is lennék coder, ha ezt nem akarnám automatizálni valahogy. iOS platformon erre kínál remek megoldást a Prowl nevű stuff.

A Prowl az OS X alatt futó Growl notification kliens fizetős iOS verziója (az app iTunes oldala erre - a post írásának pillanatában 2.39 EUR-ba kerül az alkalmazás). Mint azt már említettem korábban, OS X alatt Growl-t több cimborám az ördög szerszámának tartja, de ez ne tántorítson minket el és nézzük át, mit ad nekünk a Prowl.

A Prowl az Apple által kitalált metódus alapján (=majdnem valódi push) képes üzeneteket fogadni az iOS eszközünkön, ha hagyjuk neki (=engedélyezzük globálisan az eszközön a push notificationt a Settings/Notifications menüben, és a Prowl.app-nak is megengedjük a push üzenetek megjelenítését ugyanott).

A Prowl iOS kliensének számtalan módon küldhetünk üzenetet:

  • OS X alatt telepíthetünk Growl plugint és bármelyik Growl notificationünket átirányíthatjuk a Prowl-ba (nota bene: a Growl eleve ad egy growlnotify nevű CLI klienst, ha shell scripttel szeretnénk üzenni és természetesen benne van az AppleScript support is - ilyen felhasználásra van példa ebben az AppleScriptben).
  • Perl, PHP, Python, Ruby, Java, Lasso, .NET (Win*!), Grrovy, C platformokra ott a konyhakész API a Prowl oldalán
  • Ha a fentiek elégtelennek bizonyulnának, még mindig ott a lehetőség, hogy megírd a saját magad által választott nyelvhez az API-t.
  • Küldhetünk notificationt a Prowl saját oldalába ágyazott formból is.
  • Végül a személyes kedvenc célmegoldás: Safarinkból a 2Prowl extension segítségével az aktív browser ablak URL-jét elküldhetjük egy kattintással.

A Prowl óránként 1000 üzenetben limitálja a kiküldhető push üzenetek számát, ami a 3.6 másodperc/üzenetet alapul véve szerintem endusernek elég :)

A legszebb, hogy a Prowl kliens az iOS oldalon képes az üzenetek típus alapján történő átirányításra - íme néhány példa:

Prowl msg redirection examples

Az átirányítás definíciónál egyrészt a küldő nevét adod meg, másrészt a jelenleg Prowl által támogatott iOS alkalmazásokból választasz az üzenetnek targetet. A támogatott iOS appok listája server oldalról jön, a lista folyamatosan bővül.

Szóval ha jó lenne, ha a desktop browserből egy clickre átmászna az iPod touch/iPhone/iPad eszközre az aktív ablak URL-je, vagy épp szeretnéd, ha a Transmission szólna, hogy lejött az aktuális Debian ISO, esetleg a HandbrakeCLI-t használó scripted mondaná a mindig nálad levő telefonodnak, hogy végzett, akkor a Prowl mindenképp megér egy próbát. Egyszer ígérem még eljutunk oda is, hogy a saját házad szól rá a mobilra, hogy eleredt az eső otthon - csak győzd kivárni :)

Mac workflow: HandBrake gyípaci

Preface: mielőtt szerzői jogos hisztibe kezdene bárki - az alábbi post természetesen a saját, avi-ba konvertált, ám korábban legálisan vásárolt DVD gyűjteményem transzkódolásáról szól. Na ugorgyunk!

A tegnapi házimozis workflowból kimaradt az eFis bonus: a coder véremnek muszáj hozzátennie valamit a media centeres Nirvánához. Miután egy Perl-ben írt batch DVD konverter scriptet találtam még tegnap este a HandBrake-hez (az van linkelve az előző post-ba), agyaltam egy kicsit tovább, hogy hogy lehetne a kényelmet fokozni. Jöttek egyre vadabb ötletek, amikből készült egy röpke feature lista, aztán ern0 barátomtól jól eltanulva nagy lendülettel dobáltam ki a fancybbnél fancybb dolgokat belőle. Ennek az lett az eredménye, hogy három Excel makró tesztfutás közben megírtam egy scriptet ajándékba.

Elmesélem, hogy miket dobált elő az agyam implementálandó featureként. Az alapötlet az volt, hogy csinálok egy HandBrakeCLI-t hajtó shell scriptet, ami kihasználja a 0.9.4-es release soft subtitle opcióját és jól belegyógyítja a felirat{ok}at a transzkódolt mp4 fileokba. Ez volt a bázis, innen jött az így utólag szerintem tanulságos agymenés:

  • A HandBrakeCLI csak SRT feliratokat támogat. Nem minden felirat SRT, úgyhogy jó lenne a többi, non-SRT feliratot SRT formátumúra konvertálni.
  • Ha már ilyen okos feliratkitalációs script lesz, akkor miért ne találná ki magától, hogy milyen nyelvű a felirat?! Mi sem egyszerűbb, a Google Translate tud ilyet, van is demo oldal a language detectionról!
  • Biztos lesz egy csomó avi, amihez nem lesz felirat - ezekhez de jó lenne automatikusan keresni a neten! Hopsz, az opensubtitles.org-nak pont nyitott az API-ja, majd használjuk azt jól!

Miután ern0s vehemenciával kihúztam három izmos dolgot, elkezdtem agyalni, hogy azért valami okosság csak kellene egy rekurzív find híváson túl. Így jött az ötlet, hogy a script megkeresi, hogy van-e az avi file-ok mellé felirat és ha van, akkor bele is rámoltatja őket a készülő mp4-be.
Az algoritmus azt feltételezi, hogy a HandBrakeCLI számára használható subtitle file-ok .srt kiterjesztésűek, bázisnevük (=basename) megegyezik az avi file nevével, illetve opcionálisan a bázisnév kiegészülhetett {-en|-eng} és {-hu|-hun} tagokkal. Magyarul mondva egy példán keresztül az anyámtyúkja.avi-hoz az alábbi subtitle file-okat találja meg a script:

  • anyámtyúkja.srt
  • anyámtyúkja-hu.srt
  • anyámtyúkja-hun.srt
  • anyámtyúkja-en.srt
  • anyámtyúkja-eng.srt

A basename végéhez csapott utótag alapján dönti el a script, hogy a felirat angol vagy magyar nyelvű-e és ennek megfelelően ISO-8859-1, illetve Windows-1250 codepage-dzsel renderelteti bele a készítendő mp4 file-ba. Amennyiben az avi basename-mel megegyező nevű (=utótag nélküli) feliratfile-t talál, azt magyarnak tekinti. Az alábbi scriptben csak három darab echo szerepel, hogy a transzkódolás megindítása nélkül kipróbálhasd a scriptet - ha transzkódoltatni akarsz, az echo-kat értelemszerűen dobáld ki.

A kis minimalista toolt fds Mester lektorálta, amiért ezúton is jár a hála és a köszönet. Have fun:

#!/bin/sh
#
# Handbrake gyipaci
# lmdate 2010.07.05
#
# Végigmegy rekurzívan egy könytáron és megkeresi a filmcim-hu{n}.srt, filmcim-en{g}.srt feliratfile-okat,
# aztán ha igazán akarod, csinál neked soft subtitle-os mp4-eket az avi-jaidból.
#
# A script feltételezi, hogy ha csak egy, az avi file-lal megegyező nevű srt file-t talál, akkor abban magyar
# subtitle lakik. 
#
getsubs() {
	film="$*"
	base="${film%.*}"
	srt="$base".srt
	hu="$base"-hu.srt
	hun="$base"-hun.srt
	en="$base"-en.srt
	eng="$base"-eng.srt
 
	srthuc=0
	srthu=""
	if [ -e "$srt" ];	then
		srthuc=1
		srthu="$srt"
	elif [ -e "$hu" ]; then 
		srthuc=1
		srthu="$hu"
	elif [ -e "$hun" ]; then 
		srthuc=1
		srthu="$hun"
	fi
 
	srtenc=0
	srten=""
	if [ -e "$en" ]; then 
		srtenc=1
		srten="$en"
	elif [ -e "$eng" ]; then 
		srtenc=1
		srten="$eng"
	fi
 
	let srtc=$srthuc+$srtenc
 
	srtfiles=""
	srtcodes=""
	srtlangs=""
	case $srtc in
		0 ) ;;
 
		1 ) 
			if [ -s "$srthu" ]; then 
				srtfiles="$srthu"
				srtcodes="WINDOWS-1250"
				srtlangs="hun"
			else 
				srtfiles="$srten"
				srtcodes="ISO-8859-1"
				srtlangs="eng"
			fi
			;;
		2 ) 
			srtfiles="$srthu","$srten"
			srtcodes="WINDOWS-1250,ISO-8859-1"
			srtlangs="hun,eng"
			;;
	esac
 
	if [ $srtc -ne 0 ]; then
		echo Found $srtc subtitles:
		echo "$srtfiles"
		echo "$srtcodes"
		echo "$srtlangs"
	else
		echo No subtitles found.
	fi
 
	case $srtc in
		0 )
			# ezt az echo-t akkor dobd ki a /Applications/HandBrakeCLI elől, ha felirat nélkül is konvertálnál
			echo /Applications/HandBrakeCLI -v -i "$film" -o "$base".mp4  -e x264 -b 3000 -T -E faac -B 192 -R 48 -d slow -5 -8 medium
			;;
		1 )
			# ezt az echo-t akkor dobd ki a /Applications/HandBrakeCLI elől, ha konvertálnád a home videód akkor is, ha csak a default magyar felirat van meg hozzá
			echo /Applications/HandBrakeCLI -v -i "$film" -o "$base".mp4  -e x264 -b 3000 -T -E faac -B 192 -R 48 -d slow -5 -8 medium --srt-file "$srtfiles" --srt-codeset "$srtcodes" --srt-lang "$srtlangs"
			;;
		2 )
			# ezt az echo-t akkor dobd ki a /Applications/HandBrakeCLI elől, ha konvertálnád a home videód mind az angol, mind a magyar felirat birtokában a kétnyelvű családod számára
			echo /Applications/HandBrakeCLI -v -i "$film" -o "$base".mp4  -e x264 -b 3000 -T -E faac -B 192 -R 48 -d slow -5 -8 medium --srt-file "$srtfiles" --srt-codeset "$srtcodes" --srt-lang "$srtlangs"
		 ;;
	esac
 
	return
}
 
find . -type f -iname '*.avi' -print0 | while read -rd $'\0' f
do 
	getsubs ${f}
	echo .
done

Végül, de nem utolsósorban kiemelnék pár apró tuningot, mely a Mester nélkül nem került volna a scriptbe:

find . -type f -iname '*.avi' -print0 | while read -rd $'\0' f

A bash-ba intergrált read parancs -rd $'\0' paramétere az egyik szépség:

  • A -r nem hagyja az escape karaktereknek a "szökést", azaz pl. az Anyám\Tyúkja.avi filenéven sem bukik el a find.
  • A -d $'\0' pedig egy nulla byte-ot deklarál delimiternek, így egy buzi \n sem okoz{na} gondot a filenévben.

Szintén a Mestertől jött, hogy a magyar feliratfile-oknak ne ISO-8859-2 codepage-et definiáljak, hanem jobb lesz helyette a Windows-1250 (btw a használható codepage-ek listáját egy iconv -l mondja meg, ahogy arról a HandBrakeCLI -h is említést tesz). Ahogy ő indokolja:

ISO-8859-2-ben nincs pl „ ” vagy …

Jogos.

Mac workflow: házimozi HOWTO

Ma Mac Mini alapú media centert pakolunk össze és körbejárjuk az általam kedvelt hozzávaló software komponenseket.

A vas

Nálam egy 2. generációs Mac Mini látja el az otthoni média server feladatát. Ezt a perfekt kis Mac-et az Apple épp az elmúlt hetekben tuningolta meg: unibody házba került, vaddisznó GPU-t forrasztottak az alaplapra, akár 8 GB RAM is belefér, 1.3-as, audio jelet is szállítani képes HDMI portot integráltak bele, de ami a legfontosabb: idle állapotában 10 Wattot eszik a kis dög! Sajnos az itthoni ára ijesztően magas (240kHUF), ellenben gyönyörűséges egy szerkezet:

Mac Mini mid2010

A CEC pofon

Ha már szó esik az új Mac Miniről, nem állhatom meg, hogy ne osszak ki a gyártónak egy virtuális sallert a CEC kompatibilitás hiánya miatt 2010-ben - ezt nézzük meg kicsit belülről.

A HDMI három kommunikációs csatornát definiál: ezek sorjában a DDC, a TMDS és az opcionális CEC:

  • A DDC (=Display Data Channel) a megjelenítő eszközök paramétereit cipeli, mint kontraszt, fényerő.
  • A TMDS (=Transition Minimized Differential Signaling) hordja a képet és a hangot.
  • A CEC (Consumer Electronic Control) lenne felelős az egy HDMI láncba kötött eszközök közös vezérléséért.

HDMI_Connector_PinoutA CEC lényegében egy egy lábas soros busz a HDMI madzagban (a 13. láb az övé, a 17. láb pedig a GND-je), ami arra lenne hivatott, hogy a különböző gyártók készülékei egymás között ezen a buszon beszélgessenek és bármelyikük masterként a többit utasíthassa slave funkciók elvégzésére. Humánra fordítva ez kb. úgy hangzik, hogy a master HDMI eszközöd (jellemzően a TV) távirányítója az összes többi, a HDMI láncba kötött eszközt instruálja, azaz mondjuk a TV távirányítóján levő REC button utasíthatja a HDD rekordered, hogy kapcsoljon be, álljon be ugyanarra a csatornára, amit a TV-n nézel és kezdjen el rögzíteni. Vagy egy másik példa: legyen elég egy darab OFF button megnyomása ahhoz, hogy minden komponens (erősítő, HDD rekorder, TV) kikapcsoljon.

Csak hogy lásd, a mocsok gyártók milyen szinten sz@rnak a próbálkozásra, ami a XXI. században eljuttatná a világot a single remote Nirvánába, íme a lista a HDMI-CEC támogatás jelölésére a különböző márkák készülékein:

  • Anynet (Samsung)
  • Aquos Link (Sharp)
  • BRAVIA Sync (Sony)
  • HDMI-CEC (Hitachi)
  • Kuro Link (Pioneer)
  • CE-Link, Regza Link (Toshiba)
  • RIHD (Remote Interactive over HDMI) (Onkyo)
  • SimpLink (LG)
  • HDAVI Control, EZ-Sync, and VIERA Link (Panasonic)
  • EasyLink (Philips)
  • NetCommand for HDMI (Mitsubishi)

Klassz. Ezek után bármilyen eladót kérdezhetsz, ha nem kellően kocka, fogalma nem lesz arról, ki fia-borja az a HDMI-CEC.

A CEC dróton (13. láb) tehát bőszen küldhetnénk a Mac Miniről a TV felé a "bekapcsol + csatornát vált + hangerő beállít" commandokat, amint felébresztjük a házi almás media playerünket, de sajna az Apple-t ez egyelőre nem hatja meg. Ha a TV-n van soros port, akkor még mindig nekiállhatunk izmozni némi vezérléssel (egyszer majd lesz erről is post, ígérem), azonban amíg ez nincs, addig marad a Logitech Harmony univerzális távirányító, ami pöpecül képes vezérelni az általam is favorizált media center software-t, a Plexet is (HOWTO erre).

A software

A korrekt média gyűjtemény összeállításához az alábbi alkalmazásokat állítjuk csatasorba:

  • RipIt - egy klikkes DVD archiválás
  • FairMount - DVD mounter, ha nem kell nekünk a RipIt
  • Handbrake - videó formátumok egymásba konvertálása
  • Plex - media center a Mac-re
  • Air Video - video streamer iPhone/iPad-re
  • Rivet - az Air Video kihívója: video/audio/photo streamer iPhone/iPad-re

Mindegyikről érdemes pár szót ejteni, nézzük őket szép sorjában!

RipIt
RipIt
A RipIt rém egyszerű alkalmazás: app elindít, DVD bedug, némi pörgés azt már meg is kaptuk a másolatot a DVD-nkről. Az app jelenleg az 1.5.1-es verziónál jár, a fejlesztő srácok folyamatosan mennek utána a DVD gyártók által alkalmazott másolásvédelmi trükköknek és adják ki az újabbnál újabb release-eket (saját site-jukon áll, hogy ha találnak egy nem rippelhető DVD-t, abból beszereznek egyet és beépítik az alkalmazásukba a fixet, amint lehet).
A RipIt képes a DiscIdent DVD azonosító szolgáltatását használni ahhoz, hogy felismerje az épp rippelés alatt álló lemezt. A fejlesztők most kezdenek integrálni bele egy "Compress" névre keresztelt (egyelőre beta) feature-t, ami lényegében a DVD leghosszabb trackjének egy darab MP4 file-lá való konverzióját teszi lehetővé.
Azzal sincs gond, ha inkább a full DVD copy mellett maradnál és nem konvertálnád a lemezeidet, akkor megkérheted a RipIt-et, hogy csapja hozzá a DVD folderéhez a .dvdmedia kiterjesztést, amitől OS X alatt a folder tartalmát azonnal az óperenciás rendszerbe épített DVD Player nyitja meg.
A RipIt talán legnagyobb vonzereje, hogy a media centernek használt Mac-en futtatva "zsinórban" etetheted az alkalmazást a még be nem grabbelt lemezekkel: az esetek nagy százalékában (=amikor nincs gondja a rippelendő lemezzel) nem kell ránézned az UI-ra, mivel a kiköpött diszkről már látod, hogy adhatod neki az újabb korongot (nota bene: a RipIt a sok cimborám által gyűlölt Growl notifikációra is képes, ami meg akár értesít a munkagépen, ha kész a rip, sőt, push üzenetet küld a telefonomra a Prowl.app segítségével ha kérem, de ez majd egy másik workflow post témája lesz ;)).

FairMount

A FairMount egy olyan DVD mounter app, ami bármely DVD-t olvasó alkalmazás számára lehetővé teszi a lemez hibamentes olvasását. A FairMount fejlesztői készítik DVDRemaster nevű ripper alkalmazást is - ennek egy része a FairMount, mely a DVDRemasterrel ellentétben ingyenesen szedhető tőlük.
A FairMount-tal felcsatolt DVD lemez tartalmát tehát nagy esélyyel akár egy Finder copyval is lemásolhatod a HDD-re - onnantól pedig semmi nem állíthat meg, hogy meg ne etesd a Handbrake-kel.

Handbrake

A keresztségben a "Kézifék" nevet kapó app az igazi MP4 generátor harcos! Létezik neki remekül scriptelhető, CLI-only verziója is.
A HandbrakeCLI hajtására számos script született - ez például rekurzívan végigmegy az inputként specifikált folderben és az ott található összes VIDEO_TS mappa tartalmát könyörtelenül átzúzza mp4-be - cool.
A 0.9.4-es Handbrake kiadásban megjelent a várva várt soft subtitle támogatás, melynek segítségével kikapcsolható feliratokat (akár többet is) rendelhetünk a mozi mellé, ráadásul úgy, hogy a felirat jöhet egy külső SRT file-ból. Na, erre nemsokára varrok egy scriptet és közzé is teszem itt, csak türelem :)

Plex

A Plexről, mint a Mac-es media centerek királyáról már írtam bőven a Logitech Harmonys postban - ami mégis ide kívánkozik, az a Plex "scraper" funkciója, amivel a media librarynk metaadatait lebányássza a netről.
Nálam a filmek a /Volumes/video/film/a-film-imdb-syntax-szerinti-neve/filmcim.mp4 hierarchiában laknak. Ez a struktúra ideális a Plex scraper számára, aki szépen a háttérben gyűjtögeti a libraryban megjelent mozikhoz a metaadatot. A folder nevében az invalid folderneveket generáló karaktereket (ilyen OS X alatt a kettőspont) egyszerűen elhagyom - a Plex scraper így is megtalálja őket az adatbázisban:

Újmagyarul mondva a /Volumes/video folder a NAS-ról felmountolt AFP share. Igenám, csakhogy mind a Mac Mini, mind a NAS néha bealszanak, a NAS-t firmware update esetén újrabootolom (hosszabb áramszünet esetén az UPS teszi vele ugyanezt), azaz az AFP mount elmúlik. Így volt ez egészen Mac OS X Leopard-ig, amikor jött a megváltó automount! Az automount minden esetben megcsinálja a mountot, amint valamely alkalmazásunk az automount-ra jelölt folder tartalmához nyúlna. Nézzük meg, mi kell a fenti /Volumes/video AFP share automountjához.

Első lépésnek csinálj egy bejegyzést a /etc/fstab file-ban (sudo nano /etc/fstab):

mynas:/mozi /Volumes/video url automounted,url==afp://username:password@mynas/mozi 0 0

A fenti példára az alábbiak igazak:

  • mynas: a gép neve, ami a network share-t biztosítja
  • mozi: a network share neve a mynas gépen
  • /Volumes/video: a helyi folder neve, ahova mountoljuk az AFP share-t (=mount point)
  • username: a felhasználó neve a mynas serveren
  • password: a felhasználó jelszava a mynas serveren

Ezután már csak egy sudo automount -vc kell és már kész is a csoda: innentől kezdve az AFP share magától mountolódik, valahányszor szükséged van rá.

Air Video

Az Air Video volt az első streaming app, amire rátaláltam. Ez az alkalmazás arra képes, hogy egy tetszőleges Mac-en levő videókat iOS alapú eszközökre (iPod Touch, iPhone, iPad) streameljen. Amennyiben nem a natív H.264 kódolású videót kéred tőle, úgy képes a host gépet megkérve konvertálni, sőt, akár on-the-fly konverzióval azonnal rendelkezésre tudja bocsájtani a streamet.
Az Air Video iOS alkalmazása fizetős. A konverziót FFmpeg végzi, így a server oldal ingyen van. Az FFmpeg backendnek köszönhetően létezik belőle Linux oldali streaming server port, így háttérMac hiányában is remekül használható az app.

Rivet

A végére maradt a frissen felfedezett üdvöske, akinek a server oldala egyelőre még csak trial módban fut a munkaMac-en.
A Rivet-et ugyanaz a The Little App Factory készíti, aki az előbb már emlegetett RipIt alkalmazást. A Rivet az Air Videohoz képest zenét és képet is kiszolgál a saját iOS kliensének, ráadásul a képeket hajlandó a hagyományos folderen kívül iPhoto és/vagy Aperture libraryból is szedni - ez kell nekem!
Számtalanszor fordult már elő, hogy este megmutatnék pár napközben készült képet a családnak, amelyek a frissességükből fakadóan még nincsenek archiválva és csak a munkaMac-en laknak - erre a helyzetre tökéletes megoldást látszik kínálni a Rivet. Liszenszelés szempontjából a Rivet esetében fordított a helyzet: az iOS kliensek ingyenesek, míg a Mac-only server pénzes.

Air Video vs Rivet

Ha videóról van szó, még sokáig marad az Air Video a nyeregben: az UI egyszerűen átgondoltabb / átláthatóbb, a streaming hihetetlen zökkenésmentes. A Rivet esetében sajna ugyanezt nem tudom elmondani: a bufferelés lassú, a videóknál hajlamos valami torz aspect ratio-t használni és a kép minősége is hagy kívánnivalót maga után.
A Rivet ennek ellenére még marad: ezidáig ő az egyetlen eszköz, amivel a workMac-en lakó fotókat mutogathatom a famíliának.