diff --git a/recording.c b/recording.c
index 5293459..e51b82e 100644
--- a/recording.c
+++ b/recording.c
@@ -753,6 +753,7 @@ char *LimitNameLengths(char *s, int PathMax, int NameMax)
 
 cRecording::cRecording(cTimer *Timer, const cEvent *Event)
 {
+  id = 0;
   resume = RESUME_NOT_INITIALIZED;
   titleBuffer = NULL;
   sortBufferName = sortBufferTime = NULL;
@@ -808,6 +809,7 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event)
 
 cRecording::cRecording(const char *FileName)
 {
+  id = 0;
   resume = RESUME_NOT_INITIALIZED;
   fileSizeMB = -1; // unknown
   channel = -1;
@@ -1463,6 +1465,8 @@ time_t cRecordings::lastUpdate = 0;
 cRecordings::cRecordings(bool Deleted)
 :cList<cRecording>(Deleted ? "DelRecs" : "Recordings")
 {
+  setRecordingId = !Deleted;
+  lastRecordingId = 0;
 }
 
 cRecordings::~cRecordings()
@@ -1507,6 +1511,15 @@ void cRecordings::Update(bool Wait)
      }
 }
 
+const cRecording *cRecordings::GetById(int Id) const
+{
+  for (const cRecording *r = First(); r; r = Next(r)) {
+     if (r->Id() == Id)
+        return r;
+     }
+  return NULL;
+}
+
 const cRecording *cRecordings::GetByName(const char *FileName) const
 {
   if (FileName) {
@@ -1518,6 +1531,14 @@ const cRecording *cRecordings::GetByName(const char *FileName) const
   return NULL;
 }
 
+void cRecordings::Add(cRecording *Recording)
+{
+  if (setRecordingId)
+     // no need for locking, the caller must have a lock on the Recordigs list
+     Recording->SetId(++lastRecordingId);
+  cList<cRecording>::Add(Recording);
+}
+
 void cRecordings::AddByName(const char *FileName, bool TriggerUpdate)
 {
   if (!GetByName(FileName)) {
diff --git a/recording.h b/recording.h
index b649f6f..689f5de 100644
--- a/recording.h
+++ b/recording.h
@@ -97,6 +97,7 @@ public:
 class cRecording : public cListObject {
   friend class cRecordings;
 private:
+  int id;
   mutable int resume;
   mutable char *titleBuffer;
   mutable char *sortBufferName;
@@ -116,6 +117,7 @@ private:
   static char *StripEpisodeName(char *s, bool Strip);
   char *SortName(void) const;
   void ClearSortName(void);
+  void SetId(int Id) { id = Id; } // should only be set by cRecordings
   time_t start;
   int priority;
   int lifetime;
@@ -124,6 +126,7 @@ public:
   cRecording(cTimer *Timer, const cEvent *Event);
   cRecording(const char *FileName);
   virtual ~cRecording();
+  int Id(void) const { return id; }
   time_t Start(void) const { return start; }
   int Priority(void) const { return priority; }
   int Lifetime(void) const { return lifetime; }
@@ -220,6 +223,8 @@ class cVideoDirectoryScannerThread;
 
 class cRecordings : public cList<cRecording> {
 private:
+  bool setRecordingId;
+  int lastRecordingId;
   static cRecordings recordings;
   static cRecordings deletedRecordings;
   static char *updateFileName;
@@ -254,8 +259,11 @@ public:
   static bool NeedsUpdate(void);
   void ResetResume(const char *ResumeFileName = NULL);
   void ClearSortNames(void);
+  const cRecording *GetById(int Id) const;
+  cRecording *GetById(int Id) { return const_cast<cRecording *>(static_cast<const cRecordings *>(this)->GetById(Id)); };
   const cRecording *GetByName(const char *FileName) const;
   cRecording *GetByName(const char *FileName) { return const_cast<cRecording *>(static_cast<const cRecordings *>(this)->GetByName(FileName)); }
+  void Add(cRecording *Recording);
   void AddByName(const char *FileName, bool TriggerUpdate = true);
   void DelByName(const char *FileName);
   void UpdateByName(const char *FileName);
diff --git a/svdrp.c b/svdrp.c
index 1697cc6..607201c 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -1280,7 +1280,7 @@ void cSVDRPServer::CmdDELR(const char *Option)
      if (isnumber(Option)) {
         LOCK_RECORDINGS_WRITE;
         Recordings->SetExplicitModify();
-        if (cRecording *Recording = Recordings->Get(strtol(Option, NULL, 10) - 1)) {
+        if (cRecording *Recording = Recordings->GetById(strtol(Option, NULL, 10))) {
            if (int RecordingInUse = Recording->IsInUse())
               Reply(550, "%s", *RecordingInUseMessage(RecordingInUse, Option, Recording));
            else {
@@ -1707,7 +1707,7 @@ void cSVDRPServer::CmdLSTR(const char *Option)
            p = strtok_r(NULL, delim, &strtok_next);
            }
      if (Number) {
-        if (const cRecording *Recording = Recordings->Get(strtol(Option, NULL, 10) - 1)) {
+        if (const cRecording *Recording = Recordings->GetById(strtol(Option, NULL, 10))) {
            FILE *f = fdopen(file, "w");
            if (f) {
               if (Path)
@@ -1729,7 +1729,7 @@ void cSVDRPServer::CmdLSTR(const char *Option)
   else if (Recordings->Count()) {
      const cRecording *Recording = Recordings->First();
      while (Recording) {
-           Reply(Recording == Recordings->Last() ? 250 : -250, "%d %s", Recording->Index() + 1, Recording->Title(' ', true));
+           Reply(Recording == Recordings->Last() ? 250 : -250, "%d %s", Recording->Id(), Recording->Title(' ', true));
            Recording = Recordings->Next(Recording);
            }
      }
@@ -1940,7 +1940,7 @@ void cSVDRPServer::CmdMOVR(const char *Option)
      if (isnumber(num)) {
         LOCK_RECORDINGS_WRITE;
         Recordings->SetExplicitModify();
-        if (cRecording *Recording = Recordings->Get(strtol(num, NULL, 10) - 1)) {
+        if (cRecording *Recording = Recordings->GetById(strtol(num, NULL, 10))) {
            if (int RecordingInUse = Recording->IsInUse())
               Reply(550, "%s", *RecordingInUseMessage(RecordingInUse, Option, Recording));
            else {
