So, ich kämpfe jetzt seit 10 Tagen mit der Lösung 2.
Ich habe schon einige Probleme gelöst.
An der Berechnung der Aufnahmedauer bin ich allerdings gescheitert.
Ich habe mir jetzt geholfen, indem ich gesagt habe, wenn die Funktion in einen Fehler läuft, gebe ich die Aufnahmedauer als 1 Stunde vor.
Das scheint auch zu funktionieren. Ich weiß nur noch nicht, welche Auswirkungen, das auf meine Aufnahmen hat.
Ich habe den Code angepasst und mit reichlich neuen Kommentaren versehen.
So sieht er aktuell aus:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
#This script has the purpose to import old TVHeadend recordings in a new TVHeadend installation, when no old logs exist. It scans a folder with TVHeadend recordings and sets for each file a recording timer in TVHeadend. This is adapted from the following skript:
#https://tvheadend.org/boards/5/topics/28252?r=29113#message-29113 by user ullix tv.
#The storage folder is expected to have subfolders for each movie or series. My recordings have a filename scheme of "YYYY-MM-DDTHH-MM-xxx.ts" because I had %FT%R in the beginning of recording string. Variables have to be adapted to personal situation and scripts need either to be adapted or filenames to be renamed.
import json, urllib, time, datetime, subprocess, os
#Vordefinition der Variablen
#Folgende Anpassungen müssen gemacht werden:
#Vorgabe des Ordners der Aufnahmen über die Variable "recdir"
#Vorgabe des Benutzers des TvHeadend-Servers innerhalb der Variable "api_url"
#Vorgabe des Passworts für den Benutzer des TvHeadend-Servers innerhalb der Variable "api_url"
#Vorgabe der IP-Adresse des TvHeadend-Servers innerhalb der Variable "api_url"
recdir = "/volume1/TV-Aufzeichnungen"
recname = "my filename without .ts"
api_url = "http://*:@192.168.178.101:9981/api/dvr/entry/create?conf="
mask = """{
"enabled": true,
"start": 1000,
"stop": 2000,
"channelname": "Imported",
"title": {
"ger": "my title"
},
"comment": "added by tvh_rec_import.py",
"files": {
"filename": "/full/path/to/videofile.ts"
}
}"""
mask = mask.replace("\n", "") # remove the line feeds
#Funktion zum Ermitteln der Startzeit der Aufnahme
def filedate2num(filepath):
#Die Funktion geht davon aus, dass die Angabe von Datum und Uhrzeit der Startzeit der Aufnahme in den ersten 16 Zeichen [0:15] des Dateinamens steht.
#Datum und Uhrzeit müssen in folgender Reihenfolge aufgebaut sein und mit Bindestrichen bzw. einem Unterstrich getrennt sein 'YYYY-MM-DD_HH-MM'
#Sollten im Dateinamen auch noch Sekunden enthalten sein, werden Sie in diesem Code ignoriert, da nur die ersten 16 Zeichen betrachtet werden.
#Entspricht der Aufbau nicht der Vorgabe wird eine Fehlermeldung ausgegeben.
try:
dt = int(time.mktime(datetime.datetime.strptime(filepath.split("/")[-1][0:15], "%Y-%m-%d_%H-%M").timetuple()))
except:
print("ERROR in filestr2num: file name doesn't start with 'YYYY-MM-DD_HH-MM.ts'. Use Inode Change Time instead.")
dt = int(os.stat(filepath).st_ctime)
return dt
#Funktion zum Ermitteln der Länge/Dauer eines Videos mit Hilfe des Programms ffprobe
def videoDuration(video_file_path):
#Befehl zum Auslesen der Länge: volume1/@appstore/ffmpeg6/bin/ffprobe -loglevel quiet -print_format json -show_format /full/path/to/videofile
command = ["/volume1/@appstore/ffmpeg6/bin/ffprobe", "-loglevel", "quiet", "-print_format", "json", "-show_format ", video_file_path]
#Ausführen von "Command" und Rückgabe des Ausgabe-Strings (stdout) in die Variable "out" und des Fehlermeldungs-Strings (stderr) in die Variable "err"
pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, err = pipe.communicate()
try:
#Ausgabe-String "out" in eine Python Datenstruktur "js" umwandeln
js = json.loads(out)
#Umwandeln des Strings "js" in einen Ganzzahlwert (int)
duration = int(float(js['format']['duration']) + 1.)
except:
#Im Fehlerfall Festlegung der Länge
duration = 3600
print("Fehler bei der Berechnung der Aufnahmedauer; Ersatzwert 1h");
return duration
#Funktion zum Erstellen einer JSON-Datei mit den Informationen des Videos, um es an den Aufnahme-Timer des TvHeadend-Servers zu senden
def importRecord(filepath, mask, url):
#Die Funktion geht davon aus, dass der Dateiname folgenden Aufbau hat:
#YYYY-MM-DD_HH-MM_Chanelname_Title.ts
#Die einzelnen Bestandteile (Datum, Uhrzeit, Sender, Titel sind also mit Unterstrich getrennt
print("Datei = ",filepath)
#Funktionsaufruf zum Ermitteln der Startzeit
video_start = filedate2num(filepath)
#Funktionsaufruf zum Ermitteln der Videolänge bzw. -dauer
video_duration = videoDuration(filepath)
#Ermitteln des Dateinamens "recname" ohne Dateiendung aus der Pfadangabe "filepath"
recname = filepath.split("/")[-1][:-3]
#Erstellen einer neuen Variable als Grundlage der JSON-Datei
new_mask = json.loads(mask)
#Ermitteln des Dateinamens mit Pfadangabe aus der übergebenen Pfadangabe "filepath"
new_mask['files']['filename'] = filepath
#Ermitteln des Aufnahmetitels aus dem letzten [-1] Teilbereich des Dateinamens "recname"
new_mask['title']['ger'] = recname.split("_")[-1]
#Ermitteln des Sendernamens aus dem vorletzten [-2] Teilbereich des Dateinamens "recname"
new_mask['channelname'] = recname.split("_")[-2]
#Zuweisen der Ermittelten Startzeit "video_start"
new_mask['start'] = video_start
#Ermitteln der Stoppzeit als Summe aus der Startzeit "video_start" und der Videolänge "video_duration"
new_mask['stop'] = video_start + video_duration
print("New File Info: \n", json.dumps(new_mask, sort_keys = True, indent = 4))
api_string = url + json.dumps(new_mask)
filehandle = urllib.urlopen(api_string)
print("Server Answer:", filehandle.read())
#Hauptprogrammteil - Liest das aktuelle Verzeichnis aus und startet für jede darin enthaltene Datei mit der Endung "ts" die Funktion importRecord
directories = os.listdir(recdir)
for root, dirs, files in os.walk(recdir):
for filename in files:
if filename.endswith("ts"):
importRecord(recdir+"/"+filename, mask, api_url)
Alles anzeigen
Wahrscheinlich hat mein Code noch ein Problem damit, dass meine Dateinamen auch Leerzeichen enthalten können.
Um dieses Problem auszuschließen, habe ich die aktuelle Testaufnahme allerdings angepasst, sodass sie kein Leerzeichen enthält.
Dennoch komme ich nicht zum Ziel.
Hier meine aktuelle Fehlermeldung.
MANI@MANI-SERV2:/$ python /volume1/TV-Aufzeichnungen/tvh_rec_import.py
Datei = /volume1/TV-Aufzeichnungen/2024-02-07_18-07-00_Tele_5_Stargate.ts
Fehler bei der Berechnung der Aufnahmedauer; Ersatzwert 1h
New File Info:
{
"channelname": "5",
"comment": "added by tvh_rec_import.py",
"enabled": true,
"files": [
{
"filename": "/volume1/TV-Aufzeichnungen/2024-02-07_18-07-00_Tele_5_Stargate.ts"
}
],
"start": 1707325200,
"stop": 1707328800,
"title": {
"ger": "Stargate"
}
}
Traceback (most recent call last):
File "/volume1/TV-Aufzeichnungen/tvh_rec_import.py", line 114, in <module>
importRecord(recdir+"/"+filename, mask, api_url)
File "/volume1/TV-Aufzeichnungen/tvh_rec_import.py", line 104, in importRecord
filehandle = urllib.urlopen(api_string)
AttributeError: module 'urllib' has no attribute 'urlopen'
Alles anzeigen
Kann mir jemand bei der Lösung weiterhelfen?
Ich muss sonst leider hier abbrechen. Ich weiß einfach nicht mehr weiter.