Das müsste sich MarkusE aber ansehen
Da das nichts mit html zu tun hat, wovon ich keine Ahnung habe, versuche ich mich mal selber dran.
Das müsste sich MarkusE aber ansehen
Da das nichts mit html zu tun hat, wovon ich keine Ahnung habe, versuche ich mich mal selber dran.
Hier mal mein Vorschlag dazu. Wenn eine laufende Aufnahme gelöscht wird, wird der zugehörige Timer deaktiviert. Mir fällt kein Fall ein, an dem es Sinn macht, den Timer zu einer gelöschten Aufnahme weiterlaufen zu lassen.
Bitte testen.
Ich habe mir nur mal kurz den Code angeschaut. Du verwendest Timer->OnOff() des VDR. In Live gibt es aber eine Funktion:
… die in Folge:
… aufruft. Diese verwendet intern das SVDRP-Protokoll, um Timer zu (de)aktivieren – egal, ob sie lokal oder remote sind. Vielleicht solltest du dir das einmal genauer anschauen, denn damit könnte das Ganze deutlich einfacher werden (nur mal eben grob skizziert):
if (cTimer *Timer = rc->Timer()) {
int timerId = Timer->Id();
const char* remote = GetRemoteServer(Timer); // wie auch immer das geht
TimerManager().ToggleTimerActive(timerId, remote);
}
Um Single Events brauchst du dich eigentlich auch nicht kümmern: Wenn du per ToggleTimerActive() bzw. SVDRP einen periodischen Timer deaktivierst, wird stoppt ihn der VDR für die laufende Aufzeichnung und schaltet ihn für die nächste geplante Aufzeichnung wieder scharf. Das von SVDRP aufgerufene Timer->OnOff() kümmert sich, wenn ich es richtig eingeordnet habe, um all das.
Die Toggle Funktion kenne ich, die habe ich sogar mal vor grauer Vorzeit für remote Timer erweitert. Leider kann ich die hier nicht verwenden, da die selbst einen Timer Lock macht. Der müsste aber vor dem Recording Lock sein. Also habe ich das mir VDR Bordmittel gelöst. Man könnte natürlich noch einen Parameter für die Toggle Funktionskette einführen, die dann den Lock verhindert. Ich wollte aber die Änderung so klein wie möglich halten. MarkusE Deine Meinung dazu ?
Die Prüfung auf SingleEvent habe ich aus der VDR OSD Funktion "Aufzeichnung löschen" kopiert. Da ich keine periodischen Timer verwende (geht das überhaupt mit Live ?) wollte ich die Timer nicht anfassen. Die Funktion ist wie bisher, Aufnahme wird nicht gelöscht. Kann man ändern, wenn sinnvoll. Kann ich aber dann nicht testen.
Da ich keine periodischen Timer verwende (geht das überhaupt mit Live ?) wollte ich die Timer nicht anfassen. Die Funktion ist wie bisher, Aufnahme wird nicht gelöscht. Kann man ändern, wenn sinnvoll. Kann ich aber dann nicht testen.
Klar geht das:
Die Toggle Funktion kenne ich, die habe ich sogar mal vor grauer Vorzeit für remote Timer erweitert. Leider kann ich die hier nicht verwenden, da die selbst einen Timer Lock macht. Der müsste aber vor dem Recording Lock sein.
Deaktiviere den Timer doch vor dem Recording Lock oder terminiere die Locks vorher. Das müsste doch möglich sein.
Die Toggle Funktion kenne ich, die habe ich sogar mal vor grauer Vorzeit für remote Timer erweitert. Leider kann ich die hier nicht verwenden, da die selbst einen Timer Lock macht. Der müsste aber vor dem Recording Lock sein.
Erst Timer de-aktivieren (hier noch kein recording lock), danach Recording löschen. Müsste doch gehen (?).
Ich glaube nicht, dass das zulässig wäre:
Ich muss ja das passende Timerelement haben, das deaktiviert werden soll. Und das bekomme ich aus dem Recording Element. Und das bekomme ich über die Suche in der Liste der Recordings über dem Hash. Und die Suche braucht ein Recording Lock.
int RecordingsManager::DeleteRecording(cSv recording_hash, std::string *name)
{
LOCK_TIMERS_WRITE; // must be before LOCK_RECORDINGS_WRITE
Timers->SetExplicitModify();
LOCK_RECORDINGS_WRITE;
cRecording *recording = const_cast<cRecording *>(RecordingsManager::GetByHash(recording_hash, Recordings)); //LOCK_RECORDING
if (!recording) return 1;
if (name) *name = cSv(recording->Name());
// check if recording is activ
std::string l_name(recording->FileName());
if (cRecordControl *rc = cRecordControls::GetRecordControl(l_name.c_str())) {
// local timer is activ
if (cTimer *Timer = rc->Timer()) { // now we have the timer element to toogle
...
Display More
Klar geht das:
OK, das kannte ich nicht, ich nehme dafür Suchtimer.
Wenn du per ToggleTimerActive() bzw. SVDRP einen periodischen Timer deaktivierst, wird stoppt ihn der VDR für die laufende Aufzeichnung und schaltet ihn für die nächste geplante Aufzeichnung wieder scharf.
Stimmt, Sonderbehandlung für periodische Timer entfernt.
Ich habe da vermutlich noch ein Verständnisproblem. Möglicherweise auch deshalb, weil ich nur einen VDR betreibe und somit das Remote-Management einer anderen VDR-Instanz nicht aus eigener Anschauung kenne. Was mir unklar ist, ist Folgendes:
Für die Durchführung einer Aufnahme benötigt eine VDR-Instanz doch zwingend einen lokalen Timer, oder nicht? Zwar mag sich dieser Timer aus der Ferne managen lassen, sodass es dort in der Ferne einen Proxy gibt, aber die Aufzeichnung wird letztlich durch einen lokalen Timer gestartet und beendet. Denn cTimers::GetMatch() überspringt bei der Entscheidung, ob eine Aufnahme gestartet werden soll, als remote gekennzeichnete Timer einfach.
Da also eine zu löschende Aufzeichnung zwangsläufig immer mit einem lokalen Timer verknüpft ist, liegen beide auf ein und derselben Maschine. Insofern verstehe ich die Fallunterscheidung zwischen lokalen und Remote-Timern in deinem Code nicht: Beim Löschen einer laufenden Aufzeichnung muss man nur den lokalen Timer deaktivieren, mehr nicht. Der ferne Proxy wird dann hoffentlich schon irgendwie aktualisiert, nicht anders, als wenn man den Remote-Timer auf dem Zielrechner (Remote-Host) lokal löscht.
Wenn man sich also mit Live zu einer bestimmten VDR-Instanz verbindet und dort bei der Auflistung ihrer Aufzeichnungen das Löschen-Icon anklickt (oder nach Auswahl den Button "Markierte löschen" betätigt), dann muss man auf dieser VDR-Instanz nur deren lokale(n) Timer löschen. Es sei den, Live kann auch Aufzeichnungen auf Remote Hosts anzeigen und managen… wozu ich im Code nichts gefunden habe.
MarkusE, kann Live Aufzeichnungen auf Remote-Hosts (ähnlich wie Remote-Timer) miteinander anzeigen oder muss man sich dafür immer erst auf einem Remote-Host einloggen?
Ich versuche mal mein System zu beschreiben, vielleicht wird es dann klarer:
Ich habe zwei VDRs, jeweils in einem eigenen Container auf dem gleichen Host am Laufen (Produktiv und Test). Beide sind Headless, Live als Oberfläche zum Timer und Aufnahmen verwalten. Beide nutzen das gleiche Aufnahmeverzeichnis als Shared Folder des Hosts auf dem die Container laufen. Die VDRs tauschen die Timer über die svdrp Verbindung aus. Die Aufnahmeliste ist auf beiden gleich, da sie ja aus dem gleichen Verzeichnis lesen.
Für die Durchführung einer Aufnahme benötigt eine VDR-Instanz doch zwingend einen lokalen Timer, oder nicht?
Der VDR, der dann tatsächlich aufnimmt, hat einen lokalen Timer. Der kann aber durchaus von Live des anderen VDRs angelegt worden sein.
Da also eine zu löschende Aufzeichnung zwangsläufig immer mit einem lokalen Timer verknüpft ist, liegen beide auf ein und derselben Maschine.
Nein, wenn sich beide VDRs das gleiche Aufnahmeverzeichnis teilen, kann gerade ein remote Timer aufnehmen.
Danke, das erklärt doch Einiges. Bei mir ist das ein wenig anders: Ich nutze einen Rechner exklusiv und produktiv als VDR. Meine Testumgebung läuft hingegen in einer virtuellen Maschine auf einem anderen Rechner. Beide haben ihre eigenen Video-Verzeichnisse, weil mir das Risiko, beim Testen wertvolle Aufzeichnungen zu beschädigen oder zu verlieren, einfach zu groß ist. Wenn ich zum Testen ein paar Videos benötige, schneide ich mir ein paar nur wenige Minuten lange Schnipsel nach Bedarf zusammen oder kopiere zeitweilig nur kurz laufende Aufzeichnungen. Und auch Timer lege ich auf dem Testsystem nur lokal an, weil ich nicht möchte, dass die zu Testzwecken erstellten Timer-Kombinationen meine "echten" Timer beeinflusst oder dort zu (manchmal testhalber benötigten) Konflikten führt.
In deinem Setup wird es immer Szenarien geben, die "normale" Nutzer überhaupt nicht betreffen. Einen lokalen Timer vor dem Löschen einer Aufzeichnung zu deaktivieren, das fehlt auf jeden Fall – und der Code dafür ist doch recht übersichtlich (der if-Teil). Aber den Ballast für den Remote-Timer mitzuschleppen, erscheint mir fraglich.
Aus meiner Sicht wäre somit dieser Patch für die Allgemeinheit sinnvoll:
diff --git a/recman.cpp b/recman.cpp
index 80a3fa2..927fcf4 100644
--- a/recman.cpp
+++ b/recman.cpp
@@ -184,13 +184,22 @@ Otherwise, the rec tree is re-created from currnet data.
int RecordingsManager::DeleteRecording(cSv recording_hash, std::string *name)
{
+ LOCK_TIMERS_WRITE; // must be before LOCK_RECORDINGS_WRITE
+ Timers->SetExplicitModify();
LOCK_RECORDINGS_WRITE;
cRecording *recording = const_cast<cRecording *>(RecordingsManager::GetByHash(recording_hash, Recordings));
if (!recording) return 1;
if (name) *name = cSv(recording->Name());
-
- if (recording->IsInUse() ) return 2;
-
+ // check if recording is active
+ cSv fileName(recording->FileName());
+ if (cRecordControl *rc = cRecordControls::GetRecordControl(fileName.data())) {
+ // local timer is active
+ if (cTimer *Timer = rc->Timer()) {
+ isyslog("live: deactivating local timer %s before deletion of recording %s", *Timer->ToDescr(), name->c_str());
+ Timer->OnOff();
+ Timers->SetModified();
+ }
+ }
std::string l_name(recording->FileName());
bool result = recording->Delete();
Recordings->DelByName(l_name.c_str());
Display More
Aber letztlich muss Markus entscheiden, was davon er in die offizielle Codebasis übernehmen möchte und was du dir lokal selbst reinpatchen musst. In meinem Fall sind das doch etliche Codezeilen, damit Live so flutscht, wie ich es mir wünsche. ![]()
Aber den Ballast für den Remote-Timer mitzuschleppen, erscheint mir fraglich.
Live unterstützt Remote Timer schon seit langen, somit muss es konsequenter Weise auch dabei unterstützt werden. Es ist nicht automatisch Ballast, weil du es nicht nutzt. Du kannst es dir ja wieder raus patchen falls MarkusE das übernimmt.
Live unterstützt Remote Timer schon seit langen, somit muss es konsequenter Weise auch dabei unterstützt werden.
Schon, aber dein Szenario geht vielleicht etwas an der ursprünglichen Zielsetzung von Remote-Timern vorbei. Ich vermute, an mehrere Remote-Hosts mit gemeinsamen Video-Verzeichnis hatte seinerzeit keiner gedacht, sondern eher an jeweils in sich geschlossene VDR-Instanzen. Und Live managt nach meiner Auffassung auch immer nur einen in sich geschlossenen (Remote) Host. Wie gesagt, Markus soll sich dazu eine Meinung bilden.
Und rauspatchen muss ich den zusätzlichen Code ja nicht, denn dieser bleibt bei mir ja inaktiv. ![]()
Aber lass uns deswegen keine Grundsatzdiskussion anfangen. Ich wollte nur hinterfragen, ob man den zweiten, durchaus komplexen (und angesichts von DoToggle() funktional redundanten) Code auch wirklich braucht.
Ich vermute, an mehrere Remote-Hosts mit gemeinsamen Video-Verzeichnis hatte seinerzeit keiner gedacht
Ich zitiere mal aus der VDR man page:
-i instance, --instance=instance
Use instance as the id of this VDR instance (default is 0). In an environment where several instances of VDR use the same video directory, this parameter can be set to a positive integer value that's unique for each instance, so that they won't interfere with each other in case they record exactly the same broadcast. The number given here will be part of the directory name in which the recordings will be stored.
Also kls hat daran gedacht.
Ich glaube nicht, dass das zulässig wäre:
Ich muss ja das passende Timerelement haben, das deaktiviert werden soll. Und das bekomme ich aus dem Recording Element. Und das bekomme ich über die Suche in der Liste der Recordings über dem Hash. Und die Suche braucht ein Recording Lock.
Code Display Moreint RecordingsManager::DeleteRecording(cSv recording_hash, std::string *name) { LOCK_TIMERS_WRITE; // must be before LOCK_RECORDINGS_WRITE Timers->SetExplicitModify(); LOCK_RECORDINGS_WRITE; cRecording *recording = const_cast<cRecording *>(RecordingsManager::GetByHash(recording_hash, Recordings)); //LOCK_RECORDING if (!recording) return 1; if (name) *name = cSv(recording->Name()); // check if recording is activ std::string l_name(recording->FileName()); if (cRecordControl *rc = cRecordControls::GetRecordControl(l_name.c_str())) { // local timer is activ if (cTimer *Timer = rc->Timer()) { // now we have the timer element to toogle ...
Lese doch mal Wie prüfe ich, ob es das Event, das von timer->Event(); zurückggegeben wird, noch existiert? , insbesondere Klaus Antwort.
Ich würde sagen:
müsste doch gehen?
Das würde gehen, ist aber aus Performance Sicht nicht sinnvoll.
Aufzeichnung löschen (mit LOCK_RECORDINGS_WRITE; nach dem LOCK_RECORDINGS_WRITE erst noch prüfen, ob es die Aufnahme noch gibt).
Da man den alten Pointer nach der Freigabe vom LOCK nicht mehr verwenden kann, muss man das Recording Element nach dem zweiten LOCK erst wieder in der Liste der Aufnahmen suchen. Die kann lang sein. Nur dafür, nicht VDR Methoden zu verwenden, ist der zusätzliche Rechenaufwand nicht wert.
Der Code ist so außerdem von der VDR OSD Funktion für "delete timer" übernommen, kann also nicht ganz sinnlos sein.
The number given here will be part of the directory name in which the recordings will be stored.
Erwischt, ist halt schon einige Zeit her, seit ich dort nachschlagen musste. Aber das heißt doch, dass jede VDR-Instanz ein eigenes Video-Verzeichnis führt, also bspw. /video (ohne -i), /video1 für -i 1, /video2 für -i 2 usw. Da Live diesen Pfad vom VDR-Host bekommt, heißt das doch, dass Live nur eines davon sieht. Es sei denn, man weicht von Klaus' Empfehlung ab und vergibt keine Instanznummern.
Aber das heißt doch, dass jede VDR-Instanz ein eigenes Video-Verzeichnis führt
Nein, nur die letzte Verzeichnis Ebene einer Aufnahme hat die Kennung.
Diese Aufnahme wurde vom VDR mit der ID=1 aufgenommen. Diese Funktion soll absichern, das wenn mehrere VDRs die gleiche Sendung aufnehmen (nicht sinnvoll, aber kann ja versehentlich vorkommen), dass sie nicht in das gleiche Verzeichnis schreiben wollen.
Da Live diesen Pfad vom VDR-Host bekommt, heißt das doch, dass Live nur eines davon sieht.
Nein, weil der Pfad zum Video Verzeichnis gleich ist. Live zeigt die gleiche Aufnahmeliste auf beiden VDRs mit allen Aufnahmen, egal, welcher VDR die aufgenommen hat.
Danke für die Erläuterung. Man lernt eben nie aus… ![]()
OK, das kannte ich nicht, ich nehme dafür Suchtimer.
Stimmt, Sonderbehandlung für periodische Timer entfernt.
Hast Du diesen Patch "delete.txt" getestet? Da wird "HandleRemoteTimerModifications" verwendet, und diese Methode ist in "menu.c" definiert.
Don’t have an account yet? Register yourself now and be a part of our community!