Freitag, 6. Januar 2012

Smarter aufzeichnen mit dem vernetzten persönlichen Videorecorder (EyeTV als PVR)

Ein anständiger Festplattenrekorder macht das Fernsehkonsumenten Leben inzwischen wesentlich leichter: Aufnahmen sind dank der EPG schnell programmiert, die Geräte nehmen wenig Platz weg und können hunderte Filme archivieren.  Und Timeshift für das "Live" Fernsehen gibt es gratis dazu. Ich möchte auf diese Dienste nicht mehr verzichten - ca 95% des Fernsehens konsumiert unser Haushalt inzwischen aus der digitalen Konserve.
Die zeitliche Entkopplung, wann eine Fernsehsendung betrachtet wird, funktioniert mit den marktgängigen Geräten inzwischen problemlos. Etwas anspruchsvoller wird es, wenn die Aufzeichnungen mal schnell an einem anderen Ort ohne den Festplattenrecorder betrachtet werden sollen. Die Geräte dieser Gerätegattung geben sich, was den Zugriff auf die Videodaten angeht, meistens sehr verschlossen. Hinzu kommen Restriktionen durch die Verschlüsselung der Sender. Und an einen bequemen Videoschnitt, um z.B. Werbeunterbrechungen zu entfernen, ist meist gar nicht zu denken.

1. PROBLEMSTELLUNG
Innerhalb einer Wohnung sollen aufgenommene Fernsehaufzeichnungen mit verschiedenen Geräten, die über ein Netzwerk verbunden sind, wiedergeben werden. Dies soll ohne kopieren oder Neukodierung der Daten erfolgen.
Skizze Szenario vernetzter PVR


1.1. Funktionale Anforderungen

  • verwalten der Aufnahmen (programmieren / löschen)
  • Videoschnitt ermöglichen
  • Universal Plug and Play (UPnP) Unterstützung für Videowiedergabe (PS3, SetTop Box, Mobile Devices/Tablett PC App )
  • Wiedergabe auf Computer


1.2 Sonstige Anforderungen

  • zeitnaher Zugriff auf neue Aufnahmen. Kein erneutes kodieren oder umkopieren der Aufnahmen
  • Energiesparende Lösung


2. LÖSUNGSMÖGLICHKEITEN
2.1 PVR Hardware Device (Siemens Gigaset M740AV) und Cowfish Streaming Server
Ein Gerät, das die Möglichkeit bietet die Aufnahmen auf einem NAS abzulegen, ist die DVB-T Box von Siemens mit eingebauten Twin-Tuner.  Zwei entsprechend vernetzte Geräte hatten wir seit der Verfügbarkeit von DVB-T in unserem Haushalt in Betrieb. Zur Wiedergabe der Aufnahmen auf einem Rechner und zum leichteren Videoschnitt entwickelte ich eine JAVA Software, den "Cowfish Streamig Server" (siehe http://sourceforge.net/projects/cowfishserver  bzw. http://cowfishserver.sourceforge.net ).

Seitdem sich jedoch die EPG der Siemens Boxen nicht mehr aktualisieren liess, mussten wir uns nach einer anderen PVR Lösung umsehen. Leider wird das Gerät seit einigen Jahren nicht mehr weiterentwickelt. Eine vergleichbare fertige Hardwarelösung ist mir bei der Recherche jedoch noch nicht aufgefallen.

2.2 Computer Lösung (EyeTV/Mediacenter)
Anstatt eines fertigen Gerätes lässt sich natürlich auch ein Computer mit der entsprechenden Zusatzhardware in einen digitalen Videorecorder umwandeln. Mit entsprechenden Software-Erweiterungen liesse sich eine Videoverteilung sicherlich realisieren. Ein Arbeitskollege gab mir den Tip hierzu EyeTV einmal näher anzusehen. Was ich dann auch tat :->

2.3 Internet Videorecorder / Video On Demand
Sicherlich das Ding der Zukunft. Momentan finde ich das Angebot aber noch zu unattraktiv.


2.4 Meine Idealvorstellung (Hardware PVR Device)
Die Siemens DVB-T Boxen waren schon recht nah an meiner Idealvorstellung eines PVR Devices dran. So könnte ein Gerät aussehen:

  • Das Gerät wird mit dem lokalen Netzwerk verbunden
  • Konfiguration und Programmierung erfolgt via Web-Interface (Web Browser)
  • Null Energieverbrauch, sofern das Gerät nicht aufzeichnet oder verwaltet wird. Wake On Lan für Administration und Programmierung.
  • Aufnahmen werden auf externen Netshares abgelegt (UPnP NAS). WOL Option für NAS
  • Filter für EPG: "will ich nicht sehen", Flexibel konfigurierbare Aufnahmeregeln.
  • Videoschnittlösung für Aufnahmen. 


3. UMSETZUNG MIT EyeTV UND AppleScript
Als "Mac Haushalt" in welchem die Software EyeTV bereits seit längerem im Betrieb ist, fiel die Auswahl auf die Elgato Fernsehsoftware.  Mit dieser lassen sich auf Apple Rechnern Fernsehaufnahmen leicht programmieren,  schneiden und natürlich  auch betrachten.

Folgende Punkte mussten jedoch noch angepasst werden:

  1. Das Verzeichnis für die aufgenommenen Sendungen enthält auch immer den Timeshift-Buffer und die geplanten Aufnahmen.  Greifen mehrere EyeTV Instanzen parallel auf dasselbe zentrale Verzeichnis zu kommt es zu Konflikten mit dem TimeshiftBuffer und den geplanten Aufnahmen. Auch wäre das NAS für den Timeshift Buffer zu langsam. Letztendlich müssen lediglich die komplett aufgenommenen Sendungen auf dem NAS abgelegt werden. Hierzu bietet EyeTV jedoch keine Konfigurationsmöglichkeit.
  2. Die Energiebilanz ist hässlich, da der Mac nicht automatisch nach erfolgter Aufnahme in den Ruhezustand wechselt oder den Rechner ausschaltet. Das Aufwecken bzw. booten des Rechners für programmierte Aufnahmen funktioniert hingegen tadellos. 

Nach kurzer Recherche fanden sich Lösungsmöglichkeiten für die Zwei Punkte mittels der AppleScript Schnittstelle von EyeTV:

  1. Im EyeTV Archive-Verzeichnis wird ein symbolischer Link auf das ein via SMB gemountetes NAS Verzeichnis angelegt (ln -s /Volumes/media/SharedEyeTV/ SharedEyeTV). Nach abgeschlossener Aufnahme verschiebt ein AppleScript die Aufnahme in die NAS Freigabe.  In Christopher Kampmeier's Blog "Fun with EyeTV and AppleScript" fand ich das AppleScript Grundgerüst. Speziell die Aufteilung in RecordingDone und RecordingDone-called habe ich übernommen. Hinzu kamen noch zusätzliche mount Befehle für das NAS, da MacOS diese zwischendurch gerne wieder vergisst. Des weiteren muss eyeTV neu gestartet werden, damit die Aufnahmeliste aktualisiert wird.
  2. Der Wechsel in den Ruhezustand wird ebenfalls via AppleScript-Hook durchgeführt. Steht in den nächsten 3 Stunden keine Aufnahme an, so wird der Rechner heruntergefahren. Steht in den nächsten 30 Minuten keine Aufnahme an, so wechselt er in den Ruhezustand.  Die Skriptlogik hierzu fand ich im MacUser.de Community Forum im Posting des Users "oneOeight" "EyeTV3 RecordingDone Script zum ausschalten". Hinzu kamen noch Prüfroutinen, ob iTunes gerade ein Musikstück wiedergibt, oder ob in den letzten n Sekunden eine Interaktion durch den Benutzer stattfand. In diesen Fällen soll der Rechner nicht heruntergefahren werden.





3.1 Die AppleScript Dateien
Die folgenden AppleScript Dateien müssen in das Verzeichnis
   /Library/Application\ Support/EyeTV/Scripts/TriggeredScripts
abgelegt werden:

  • ExportDone.scpt
  • RecordingDone.scpt
  • RecordingDone-called.scpt
Der Pfad zum "mounten" des NAS muss für andere Installationen sicherlich angepasst werden...


3.1.1 RecordingDone.scpt

-- this script reuses modified AppleScript snippets of the following sources:
-- a) Christopher Kampmeier's Blog "Fun with EyeTV and AppleScript" (Script Structure)
-- b) MacUser.de Community Forum, by user oneOeight "EyeTV3 RecordingDone Script zum ausschalten"
-- TST 2012/01

-- If you would like to unit test the RecordingDone script, you can rename it, 
-- make several recordings and then call the renamed script directly from a 
-- terminal window like this:
--     $ osascript RecordingDoneTest.scpt 2
-- Where “2″ represents the second recording in your list.


property ARCHIVE_DIR : "~/Documents/EyeTV\\ Archive/"
property LOGFILE : ARCHIVE_DIR & "/osascript.log"


on RecordingDone(recordingID)
do shell script "echo \"recordingID = " & recordingID & "\" >" & LOGFILE & ""
do shell script "nohup osascript /Library/Application\\ Support/EyeTV/Scripts/TriggeredScripts/RecordingDone-called.scpt " & recordingID & " >> " & LOGFILE & " 2>&1 &"
end RecordingDone

on run argv
set myItem to item 1 of argv as integer
tell application "EyeTV"
set rec to unique ID of item myItem of recordings
end tell
my RecordingDone(rec)
end run



3.1.2 ExportDone.scpt

-- this script reuses modified AppleScript snippets of the following sources:
-- a) Christopher Kampmeier's Blog "Fun with EyeTV and AppleScript" (Script Structure)
-- b) MacUser.de Community Forum, by user oneOeight "EyeTV3 RecordingDone Script zum ausschalten"
-- TST 2012/01


-- If you would like to unit test the RecordingDone script, you can rename it, 
-- make several recordings and then call the renamed script directly from a 
-- terminal window like this:
--     $ osascript RecordingDoneTest.scpt 2
-- Where “2″ represents the second recording in your list.

property ARCHIVE_DIR : "~/Documents/EyeTV\\ Archive/"
property LOGFILE : ARCHIVE_DIR & "/export.log"


on ExportDone(recordingID)
do shell script "echo \"recordingID = " & recordingID & "\" >>" & LOGFILE & ""
do shell script "nohup osascript /Library/Application\\ Support/EyeTV/Scripts/TriggeredScripts/RecordingDone-called.scpt " & recordingID & " >> " & LOGFILE & " 2>&1 &"
end ExportDone

on run argv
set myItem to item 1 of argv as integer
tell application "EyeTV"
set rec to unique ID of item myItem of recordings
end tell
my RecordingDone(rec)
end run       

3.1.3 RecordingDone-called.scpt
-- this script reuses modified AppleScript snippets of the following sources:

-- a) Christopher Kampmeier's Blog "Fun with EyeTV and AppleScript" (Script Structure)
-- b) MacUser.de Community Forum, by user oneOeight "EyeTV3 RecordingDone Script zum ausschalten"
-- TST 2012/01


-- RecordingDone-called.scpt
--   copyRecord()            : moves recording from local HDD to a shared network drive 
--   checkEnergySaving(): switches mac to sleeps or shutdown after EyeTV completes a recording 

property ARCHIVE_DIR : "~/Documents/EyeTV\\ Archive"
property NETSHARED_DIR : "/Volumes/media/video/SharedEyeTV"


on run argv
set recordingID to item 1 of argv
-- manually started converter job?
set posix_recording_path to getPOSIXRecordingPath(recordingID)
if not (posix_recording_path contains "SharedEyeTV") and noExportJobFor(recordingID) then
try
moveRecordToNAS(recordingID)
on error errorText
log "copy record failed: " & errorText
end try
checkEnergySaving()
end if
end run

on checkEnergySaving()
if not eyeTVisBusy() then
-- Quelle für Vorlage: MacUser.de Community Forum, user oneOeight "EyeTV3 RecordingDone Script zum ausschalten"
set ausschalten to my keineAnstehendeAufnahmeIn(180)
set ruhezustand to my keineAnstehendeAufnahmeIn(30)
tell application "EyeTV" -- fuer activate und display dialog
if ausschalten then
activate
beep
set antwort to display dialog "TV Aufnahme beendet - Ausschalten?" buttons {"nein", "ja"} default button "ja" giving up after 30
if button returned of antwort = "ja" or button returned of antwort = "" then
log (current date) & "shut down computer"
tell application "Finder" to shut down
end if
else if ruhezustand then
activate
beep
set antwort to display dialog "TV Aufnahme beendet - Ruhezustand?" buttons {"nein", "ja"} default button "ja" giving up after 30
if button returned of antwort = "ja" or button returned of antwort = "" then
log (current date) & "setting computer to sleep"
tell application "System Events" to sleep
end if
end if
end tell
end if
end checkEnergySaving

on noExportJobFor(recordingID)
tell application "EyeTV"
return not is_exporting
end tell
return true
end noExportJobFor

on moveRecordToNAS(recordingID)
set posix_recording_path to getPOSIXRecordingPath(recordingID)
set myid to recordingID as integer
try
mount volume "smb://mediax/media" --mount destination file
end try
set cmd to "cp -R \"" & posix_recording_path & "\" \"" & NETSHARED_DIR & "\""
log "running \"" & cmd & "\""
do shell script "" & cmd & ""
tell application "EyeTV"
delete recording id myid
end tell
if not eyeTVisBusy() then
restartEyeTV()
end if
end moveRecordToNAS

on getPOSIXRecordingPath(recordingID)
tell application "EyeTV"
set myid to recordingID as integer
set recording_location to location of recording id myid as text
set AppleScript's text item delimiters to "."
set recording_path to text items 1 through -3 of recording_location as string
set AppleScript's text item delimiters to ""
set recording_path to POSIX path of recording_path & ".eyetv"
end tell
return recording_path
end getPOSIXRecordingPath


on restartEyeTV()
with timeout of 60 seconds
tell application "EyeTV"
quit
end tell
delay 10
tell application "EyeTV"
launch
end tell
end timeout
end restartEyeTV

on eyeTVisBusy()
tell application "EyeTV"
return is_recording or is_exporting or is_saving_clip_as_recording
end tell
end eyeTVisBusy

-- steht innerhalb der nächsten xx Minuten (zeit) keine Aufnahme an?
-- Quelle für Vorlage: MacUser.de Community Forum, by user oneOeight "EyeTV3 RecordingDone Script zum ausschalten"
on keineAnstehendeAufnahmeIn(zeit)
tell application "EyeTV"
try
set limit to zeit * minutes
set ausmachen to true
set vorlauf to (prepad time + 2) * minutes
set jetzt to current date
repeat with aufnahme in start time of programs
set diff to aufnahme - jetzt
if diffvorlauf then set diff to diff - vorlauf
if diff ≥ 0 and difflimit then set ausmachen to false
end repeat
end try
end tell
return {ausmachen}
end keineAnstehendeAufnahmeIn


3.1.4 InitEyeTV.scpt - AppleScript bei Anmeldung ausführen
Letztendlich übernimmt noch ein weiteres kleines AppleScript als Anmeldeobjekt bei der Anmeldung das Mounten des NAS Laufwerks und den Neustart der eyeTV-Software, damit die im NAS abgelegten Aufnahmen gelistet werden.


--  mount shared eyetv folder 
-- and restart eyetv to reload recordings 
--
-- launch this script at user login
-- T.Stroeter/Januar 2012 

property MOUNTVOLUME : "smb://mediax/media"


on run argv
mountSharedArchive()
restartEyeTV() -- restart to reload recordings
end run



on mountSharedArchive()
try
mount volume MOUNTVOLUME --mount destination file
log "mounted " & MOUNTVOLUME
on error errorText
log errorText
end try
end mountSharedArchive

on restartEyeTV()
with timeout of 60 seconds
tell application "EyeTV"
quit
end tell
delay 5
tell application "EyeTV"
launch
end tell
end timeout
end restartEyeTV




3.2 Bekannte Probleme
  • Die Daten müssen für die EyeTV-Lösung von der lokalen Platten auf das NAS umkopiert werden (kostet Zeit).
  • Die Wiedergabe unter EyeTV kann stocken, wenn das NAS die Daten zu langsam liefert. Im Gegensatz zu anderen VideoPlayer verwendet eyeTV hier offensichtlich einen zu kleinen internen Buffer für die Wiedergabe.



3.3 Todos: 
-besseres Logging: ablegen in Aufnahme-Ordner
-stabileres Shutdown nach geplanten Export Jobs


3.4 Energiebilanz
Der EyeTV PVR läuft auf unserem "Küchen iMac", 20 Zoll Modell Mitte 2007 mit 2.4GHz Core 2 Duo und 4GB RAM. Bei Aufnahme mit ausgeschalteten Display benötigt er noch 45W. Der Verbrauch im  Standby Betrieb war für das Messgerät nicht mehr anzeigbar.
Energieverbrauch des iMac 20 Zoll während der Aufnahme...
..und im Ruhezustand (Standby) 

Die Siemens Gigabset Boxen benötigten im Vergleich dazu während der Aufnahme um die 11W, im Standby um die 0,3W.

Als NAS wird eine Buffalo Linkstation mini im Dauerbetrieb verwendet. Während der Aufnahme benötigt diese ca 12,2W. Ohne Last sind es mit 7,8 W. Durch eine Zusatzsoftware für Windows und Apple Rechner ließe sich das NAS noch in einen Schlafzustand schicken und aufwecken, wodurch weitere 2-3 W gespart werden.


4. Verwendete Quellen

a) Christopher Kampmeier's Blog "Fun with EyeTV and AppleScript"
http://kampmeier.com/chris/blog/?p=451 Feb 2011
Enthielt bereits das AppleScript Grundgerüst, speziell die Aufteilung in RecordingDone und RecordingDone-called, welche ich übernommen habe.

b) MacUser.de Community Forum, User "oneOeight" "EyeTV3 RecordingDone Script zum ausschalten
  Skriptlogik, um den Rechner zuverlässig nach einer Aufnahme auszuschalten.


c) AppleScript Language Guide
    Onlineversion - lässt sich auch als komplettes PDF laden.
d) Buch "AppleScript - Der automatische Mac"
     Detlef Schulz/ Smart Books 2009

Donnerstag, 5. Januar 2012

Bye Bye Cowfish Streaming Server

Seit Sommer 2011 hatten unsere  zwei DVB-T Boxen (Siemens M740 AV) Probleme mit der EPG Aktualisierung. Ob es an Umstellungen am Düsseldorfer Fernmeldeturm lag oder die Hardware muckte - wer weiss. Auf jeden Fall erfüllten die wunderschönen Boxen ihren eigentlichen Zweck nicht mehr - als digitaler Videorecorder waren sie nicht mehr zu gebrauchen.

Somit konnte ich auch meine für die Box entwickelte Zusatzsoftware, den "Cowfish Streaming Server" ebenfalls einstampfen, da sie ja nicht nicht mehr benötigt wird. Eventuell werde ich ein par Teile (XML Konfigurationsverwaltung) noch einmal separat veröffentlichen, aber das war es wohl zunächst mit diesem Projekt.

http://sourceforge.net/projects/cowfishserver/

http://cowfishserver.sourceforge.net/ 

cowfish: Webfrontend
Cowfish: Videowiedergabe via VLC

Cowfish: Videoschnitt mit ProjectX