Real Playlists (.RPLS) File Reader

Ziel

Manchmal möchte man auf einer BluRay, zwecks Inventarisierung gewisse Informationen herausholen. Ich möchte Ihnen mit diesem Artikel, den Dateityp der Real Playlists (.RPLS) vorstellen. Im Internet sind die Informationen darüber sehr rar. Deshalb hat es mich bewogen diesen Artikel zu veröffentlichen.

Formatstrukturen

Verzeichnisstruktur

Eine BluRay auf der einen Ton (Audio) oder eine Bildfolge (Video) aufgenommen wurde hat folgende Dateiverzeichnis Struktur:

  • AACS (Advanced Access Control System Verzeichnis)
    • AACS_av\ (AACS Entschlüsselverzeichnis)
      • Unit_Key_RW.inf (ACS CPS Einheitsschlüssel-Datei)
    • MKB_RW.inf  (Lese/Schreibe Medienschlüssel Block)
  • BDAV (BlueRay Audio Video Verzeichnis)
    • PLAYLIST (Verzeichnis der Abspiellisten)
      • 00001.rpls (.rpls = Real Play Lists Dateien)
      • 00002.rpls
      • 00003.rpls
      • xxxxx.rpls (viele weitere Real Playlists)
      • xxxxx.vpls (.vpls = Virtual Play Lists Dateien)
      • xxxxx.mpls (.mpls = Movie Play Lists Dateien)
    • CLIPINF (Verzeichnis der Szeneninformationen)
      • 00001.clpi
      • 00002.clpi
      • 00003.clpi
      • xxxxx.clpi (viele weitere Clipinformationen)
    • STREAM (Verzeichnis der Videodateien)
      • 00001.m2ts
      • 00002.m2ts
      • 00003.m2ts
      • xxxxx.xxxx (Viele weitere Videodateien)
    • info.bdav (Abspiellisteninformationen)

In diesem Artikel geht um das Verzeichnis der Abspiellisten (\BDAV\PLAYLIST). Dort müssen wir unterscheiden ob es sich um eine gekaufte BluRay Material oder um auf einer BluRay aufgenommene Videos sind. Bei gekauften BluRay’s , sind die Abspieldaten als Movie Play Lists Dateien gespeichert (MPLS). Bei auf BluRay selbstgenommenen Videos (Filme, Serien, Sendungen, Kameraaufnahmen), werden die Abspieldaten als Real Playlists Dateien (RPLS) gespeichert.

Movie Play Lists Dateien (MPLS)

Die Struktur einer MPLS Datei finden Sie hier: https://en.wikibooks.org/wiki/User:Bdinfo/mpls

Real Playlists Dateien (RPLS)

Die Datei weicht von der Struktur der Movie Play Lists Datei (MPLS) ab.

Dateiformat Struktur

Offset beginnt bei der Dateistelle 0

Beginn Ende Länge Type Feld Bedeutung
0 3 4 String Header Kopfzeile (PLST)
4 7 4 String Version Version (0100)
8 49 42 ????? ?????? Unbekannte Informationen
50 56 7 Byte RecordDate Aufnahmedatum
57 59 3 Byte RecordDuration Aufnahmedauer
60 61 2 Integer MarkerID ID des Markieres
62 63 4 Integer MarkerModelCode Modelcode des Markieres
 64  64  1  ?????  ???????  Unbekannte Informationen
65 66 2 Integer ChannelNr Kanalnummer
67 67 1 Byte ChannelNameLength Länge der Zeichenkette der Kanalnummer
68 87 20 String ChannelName Kanalname (ZDF, ARD, RTL, CNN, SRF, …)
88 88 1 Byte TitelNameLength Länge der Zeichenkette des Aufgenommen Titelnamen
89 343 255 String TitelName Aufgenommener Titelnamen (007 – Goldfinger, North by Northwest, ….)
344 345 2 Integer DetailStartOffset Offset Start Stelle für Detailinformationen

Offset beginnt bei der Dateistelle 1

Beginn Ende Länge Type Feld Bedeutung
1 4 4 String Header Kopfzeile (PLST)
5 8 4 String Version Version (0100)
9 50 42 ????? ?????? Unbekannte Informationen
51 57 7 Byte RecordDate Aufnahmedatum
58 60 3 Byte RecordDuration Aufnahmedauer
61 62 2 Integer MarkerID ID des Markieres
63 64 4 Integer MarkerModelCode Modelcode des Markieres
 65  65  1  ?????  ?????  Unbekannte Informationen
66 67 2 Integer ChannelNr Kanalnummer
68 68 1 Byte ChannelNameLength Länge der Zeichenkette der Kanalnummer
69 88 20 String ChannelName Kanalname (ZDF, ARD, RTL, CNN, SRF, …)
89 89 1 Byte TitelNameLength Länge der Zeichenkette des Aufgenommen Titelnamen
90 344 255 String TitelName Aufgenommener Titelnamen (007 – Goldfinger, North by Northwest, ….)
345 346 2 Integer DetailStartOffset Offset Start Stelle für Detailinformationen

Quellcode

Visual Basic for Application (VBA)

Mit diesem Quellcode (Sourcecode) kann man den Aufgenommen Filmtitel, wann er aufgenommen wurde, wo er aufgenommen wurde und wie lange die Dauer der Aufnahme ist  ermitteln.

 Option Compare Database
Option Explicit

'.RPLS FileStruktur
Public Type RealPlayListStream              'Adressoffsett-Info (Beginn 0000 | 0001)
    Header As String * 4                    '0000 - 0003 | 0001 - 0004 (Länge 0004): Kopfzeile (PLST)
    Version As String * 4                   '0004 - 0007 | 0005 - 0008 (Länge 0004): Version   (0100)
    Dump1 As String * 42                    '0008 - 0049 | 0009 - 0050 (Länge 0042): Unbekannte Informationen
    RecordDate(0 To 6) As Byte              '0050 - 0056 | 0051 - 0057 (Länge 0007): Aufnahmedatum
    RecordDuration(0 To 2) As Byte          '0057 - 0059 | 0058 - 0060 (Länge 0003): Aufnahmedauer
    MarkerID As Integer                     '0060 - 0061 | 0061 - 0062 (Länge 0002): ID des Markieres
    MarkerModelCode As Integer              '0062 - 0063 | 0063 - 0064 (Länge 0004): Modelcode des Markieres
    Dump2 As String * 1                     '0064 - 0064 | 0065 - 0065 (Länge 0001): Unbekannte Informationen
    ChannelNr As Integer                    '0065 - 0066 | 0066 - 0067 (Länge 0002): Kanalnummer
    ChannelNameLength As Byte               '0067 - 0067 | 0068 - 0068 (Länge 0001): Länge der Kanalnummer
    ChannelName As String * 20              '0068 - 0087 | 0069 - 0088 (Länge 0020): Kanalname (ZDF, ARD, RTL, CNN, SRF, ...)
    TitelNameLength As Byte                 '0088 - 0088 | 0089 - 0089 (Länge 0001): Länge des Aufgenommen Titelnamen
    TitelName As String * 255               '0089 - 0343 | 0090 - 0344 (Länge 0255): Aufgenommener Titelnamen (007 - Goldfinger, North by Northwest, ....)
    DetailStartOffset As Integer            '0344 - 0345 | 0345 - 0346 (Länge 0002): Offset Start Stelle für Detailinformationen
End Type
Public Sub Main()
Dim oFs As New Scripting.FileSystemObject
Dim oFsFile As Scripting.File
Dim vFil As Long
Dim vRealPlayListStream As RealPlayListStream
For Each oFsFile In oFs.GetFolder("e:\BDAV\PLAYLIST").Files
    If UCase(oFsFile.Name) Like "*.RPLS" Then
        vFil = FreeFile
        Open oFsFile.Path For Binary As vFil
        Get #vFil, 1, vRealPlayListStream
        Close vFil
        Debug.Print oFsFile.Name
        Debug.Print "Titelname:        " & Left(vRealPlayListStream.TitelName, vRealPlayListStream.TitelNameLength)
        Debug.Print "Sendekanalnummer: " & vRealPlayListStream.ChannelNr
        Debug.Print "Sendekanalname:   " & Left(vRealPlayListStream.ChannelName, vRealPlayListStream.ChannelNameLength)
        Debug.Print "Aufnahme Datum:   " & ToDateTimeString(vRealPlayListStream.RecordDate, 0)
        Debug.Print "Aufnahme Dauer:   " & ToDateTimeString(vRealPlayListStream.RecordDuration, 0)
        Debug.Print vRealPlayListStream.DetailStartOffset
    End If
Next oFsFile
End Sub
Public Function ToDateTimeString(rplsDate() As Byte, FormatArt As Long) As String
    Dim vDateString As String
    Dim vTimeString As String
    Dim vCentury As Byte
    Dim vYearInnerCentury As Byte
    Dim vMonth As Byte
    Dim vDay As Byte
    Dim vHour As Byte
    Dim vMinute As Byte
    Dim vSeconde As Byte
    If UBound(rplsDate, 1) >= 6 Then
        'Datum und Uhrzeiten (Date and Time)
        vCentury = Hex(rplsDate(0))             'Jahrhundert
        vYearInnerCentury = Hex(rplsDate(1))    'Jahr innerhalb des Jahrhunderts
        vMonth = Hex(rplsDate(2))               'Monat
        vDay = Hex(rplsDate(3))                 'Tag
        vHour = Hex(rplsDate(4))                'Stunden
        vMinute = Hex(rplsDate(5))              'Minuten
        vSeconde = Hex(rplsDate(6))             'Sekunden
    ElseIf UBound(rplsDate, 1) >= 2 Then
        'Nur Uhrzeiten (Time)
        vHour = Hex(rplsDate(0))                'Stunden
        vMinute = Hex(rplsDate(1))              'Minuten
        vSeconde = Hex(rplsDate(2))             'Sekunden
    End If
    Select Case FormatArt
        Case 0                                  'Europa
            vDateString = Format(vDay, "00") & "." & Format(vMonth, "00") & "." & Format(vCentury, "00") & Format(vYearInnerCentury, "00")
            vTimeString = Format(vHour, "00") & ":" & Format(vMinute, "00") & ":" & Format(vSeconde, "00")
        Case 1                                  'UK/US
            vDateString = Format(vMonth, "00") & "/" & Format(vDay, "00") & "." & Format(vCentury, "00") & Format(vYearInnerCentury, "00")
            vTimeString = Format(vHour, "00") & ":" & Format(vMinute, "00") & ":" & Format(vSeconde, "00")
        Case 2                                  'Unformated
            vDateString = Format(vCentury, "00") & Format(vYearInnerCentury, "00") & Format(vMonth, "00") & Format(vDay, "00")
            vTimeString = Format(vHour, "00") & Format(vMinute, "00") & Format(vSeconde, "00")
    End Select
    ToDateTimeString = vDateString & " " & vTimeString
End Function

<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>

Visual Basic.NET

Imports System
Imports System.IO
Imports System.Net
Imports System.Text

Module mRPLS
    Public RPLS As RealPlayList
    Public RPLS_Stream As RealPlayListStream
    Public Structure RealPlayListStream    'Adressoffsett-Info (Beginn 0000 | 0001)
        <VBFixedString(4)> Public Header As String          '0000 - 0003 | 0001 - 0004 (Länge 0004): Kopfzeile (PLST)
        <VBFixedString(4)> Public Version As String         '0004 - 0007 | 0005 - 0008 (Länge 0004): Version   (0100)
        <VBFixedString(42)> Public Dump1 As String          '0008 - 0049 | 0009 - 0050 (Länge 0042): Unbekannte Informationen
        <VBFixedArray(6)> Public RecordDate() As Byte       '0050 - 0056 | 0051 - 0057 (Länge 0007): Aufnahmedatum
        <VBFixedArray(2)> Public RecordDuration() As Byte   '0057 - 0059 | 0058 - 0060 (Länge 0003): Aufnahmedauer
        Public MarkerID As Int16                            '0060 - 0061 | 0061 - 0062 (Länge 0002): ID des Markieres
        Public MarkerModelCode As Int16                     '0062 - 0063 | 0063 - 0064 (Länge 0004): Modelcode des Markieres
        <VBFixedString(1)> Public Dump2 As String           '0064 - 0064 | 0065 - 0065 (Länge 0001): Unbekannte Information
        Public ChannelNr As Int16                           '0065 - 0066 | 0066 - 0067 (Länge 0002): Kanalnummer
        Public ChannelNameLength As Byte                    '0067 - 0067 | 0068 - 0068 (Länge 0001): Länge der Kanalnummer
        <VBFixedString(20)> Public ChannelName As String    '0068 - 0087 | 0067 - 0088 (Länge 0020): Kanalname (ZDF, ARD, RTL, CNN, SRF, ...)
        Public TitleNameLength As Byte                      '0088 - 0088 | 0089 - 0089 (Länge 0001): Länge des Aufgenommen Titelnamen
        <VBFixedString(255)> Public TitleName As String     '0089 - 0343 | 0090 - 0344 (Länge 0255): Aufgenommener Titelnamen (007 - Goldfinger, North by Northwest, ....)
        Public DetailStartOffset As Integer                 '0344 - 0345 | 0345 - 0346 (Länge 0002): Offset Start Stelle für Detailinformationen
    End Structure
    Public Structure RealPlayList
        Public Header As String
        Public Version As String
        Public RecordDate As String
        Public RecordDuration As String
        Public ChannelNr As Integer
        Public ChannelName As String
        Public TitleName As String
    End Structure
    Public Sub ReadRPLS(ByVal FileName As String)
        Dim vFil As Integer = FreeFile()
        FileOpen(vFil, FileName, OpenMode.Binary, OpenAccess.Read)
        FileGet(vFil, RPLS_Stream)
        FileClose(vFil)
        RPLS.Header = RPLS_Stream.Header
        RPLS.Version = RPLS_Stream.Version
        RPLS.RecordDate = ToDateTimeString(RPLS_Stream.RecordDate, 0)
        RPLS.RecordDuration = ToDateTimeString(RPLS_Stream.RecordDuration, 0)
        RPLS.ChannelNr = RPLS_Stream.ChannelNr
        RPLS.ChannelName = RPLS_Stream.ChannelName.Substring(0, RPLS_Stream.ChannelNameLength)
        RPLS.TitleName = RPLS_Stream.TitleName.Substring(0, RPLS_Stream.TitleNameLength)
    End Sub
    Public Function ToDateTimeString(ByVal rplsDate() As Byte, ByVal FormatArt As Long) As String
        Dim vDateString As String
        Dim vTimeString As String
        Dim vCentury As Byte
        Dim vYearInnerCentury As Byte
        Dim vMonth As Byte
        Dim vDay As Byte
        Dim vHour As Byte
        Dim vMinute As Byte
        Dim vSeconde As Byte
        If UBound(rplsDate, 1) >= 6 Then
            'Datum und Uhrzeiten (Date and Time)
            vCentury = Hex(rplsDate(0))             'Jahrhundert
            vYearInnerCentury = Hex(rplsDate(1))    'Jahr innerhalb des Jahrhunderts
            vMonth = Hex(rplsDate(2))               'Monat
            vDay = Hex(rplsDate(3))                 'Tag
            vHour = Hex(rplsDate(4))                'Stunden
            vMinute = Hex(rplsDate(5))              'Minuten
            vSeconde = Hex(rplsDate(6))             'Sekunden
        ElseIf UBound(rplsDate, 1) >= 2 Then
            'Nur Uhrzeiten (Time)
            vHour = Hex(rplsDate(0))                'Stunden
            vMinute = Hex(rplsDate(1))              'Minuten
            vSeconde = Hex(rplsDate(2))             'Sekunden
        End If
        Select Case FormatArt
            Case 0                                  'Europa
                vDateString = Format(vDay, "00") & "." & Format(vMonth, "00") & "." & Format(vCentury, "00") & Format(vYearInnerCentury, "00")
                vTimeString = Format(vHour, "00") & ":" & Format(vMinute, "00") & ":" & Format(vSeconde, "00")
            Case 1                                  'UK/US
                vDateString = Format(vMonth, "00") & "/" & Format(vDay, "00") & "." & Format(vCentury, "00") & Format(vYearInnerCentury, "00")
                vTimeString = Format(vHour, "00") & ":" & Format(vMinute, "00") & ":" & Format(vSeconde, "00")
            Case 2                                  'Unformated
                vDateString = Format(vCentury, "00") & Format(vYearInnerCentury, "00") & Format(vMonth, "00") & Format(vDay, "00")
                vTimeString = Format(vHour, "00") & Format(vMinute, "00") & Format(vSeconde, "00")
        End Select
        ToDateTimeString = vDateString & " " & vTimeString
    End Function

End Module<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>

Ergebnis

Im Jahre 2014 zeigte RTL Nitro die Kojak Filme, dass sind die Filme, die nach dem Ende Serie (der 5 Stafel) ein paar Jahr später  produziert wurden. Ich habe diese Filme aufgenommen mit dem Panasonic Harddisk / BluRay Videorecorder Gerät und habe diese dann auf eine BluRay übertragen. Dann legte ich heute (24.10.2017) die BluRay in das Wechseldatenträgerlaufwerk meines Computers.

Wenn ich das Programm starte, kommt folgendes Ergebnis heraus:


00001.rpls
Titelname: Kojak: Mord im Exil
Sendekanalnummer: 74
Sendekanalname: RTL NITRO HD C
Aufnahme Datum: 14.05.2014 16:00:04
Aufnahme Dauer: 00.00.0000 01:40:03
0
00002.rpls
Titelname: Kojak: Ariana
Sendekanalnummer: 74
Sendekanalname: RTL NITRO HD C
Aufnahme Datum: 15.05.2014 16:00:04
Aufnahme Dauer: 00.00.0000 01:40:02
0
00003.rpls
Titelname: Kojak: Dunkle Beziehungen
Sendekanalnummer: 74
Sendekanalname: RTL NITRO HD C
Aufnahme Datum: 16.05.2014 16:00:03
Aufnahme Dauer: 00.00.0000 01:40:03
0
00004.rpls
Titelname: Kojak: Tod eines Polizisten
Sendekanalnummer: 74
Sendekanalname: RTL NITRO HD C
Aufnahme Datum: 19.05.2014 16:00:03
Aufnahme Dauer: 00.00.0000 01:40:03
0
00005.rpls
Titelname: Kojak: Gefährliche Gier
Sendekanalnummer: 74
Sendekanalname: RTL NITRO HD C
Aufnahme Datum: 20.05.2014 16:00:03
Aufnahme Dauer: 00.00.0000 01:40:03
0
00006.rpls
Titelname: Kojak: Die Verschwörung
Sendekanalnummer: 74
Sendekanalname: RTL NITRO HD C
Aufnahme Datum: 21.05.2014 16:00:03
Aufnahme Dauer: 00.00.0000 01:40:03
0


 

Ich sehe nun, dass die sechste Abspielliste, den Film „Kojak: Die Verschwörung“ enthält, das auf meinem Videorekorder dies auf dem Kanal 74 aufgenommen wurde. Dann sehe ich, dass beim Kanal 74 der Fernsehsender „RTL NITRO HD C“ eingestellt ist. Die Aufnahme wurde erfolgt am 21.05.2014 um 16:00:03. Die Dauer der Aufnahme betrug 1 Stunde 40 Minuten und 3 Sekunden. Nun kontrolliere anhand der Webseite „fernsehserien.de“ ob diese angaben stimmen: URL: https://www.fernsehserien.de/kojak-1973/folgen/07-die-verschwoerung-27749

3 Kommentare

  • Interessantes Projekt
    Das VBA-Script erzeugt in der ersten Zeile

    Dim oFs As New Scripting.FileSystemObject

    bei mir bei mir den Fehler: Benutzerdefinierter Typ nicht definiert.
    Was ist da los?

    themagicteacher

    Like

    • Sehr geehrter Herr Kowalsky

      Besten Dank für Ihr Feedback an einem Artikel in meiner Webseite. Es ist tatsächlich noch etwas was im Artikel noch fehlt.

      Für das Objekt Scripting.FileSystemObject wurde noch kein Verweis gefunden. Diesen Verweis können Sie aktivieren indem Sie folgende Schritte durchführen:
      – Im Microsoft Access Visual Basic für Applikationen den Menüpunkt Extras drücken.
      – Dann unterhalb von Hauptmenü Extra denn Menüpunkt Verweis drücken.
      – Es erscheint der Verweis Dialog. Suchen Sie nach Microsoft Scripting Runtime und Klicken Sie das Ankreuzfeld an.
      – Drücken Sie dann die Schaltfläche „OK“, um diesen Verweis zu aktivieren.

      Danach sollte es laufen.,

      Hier das Video:
      [video src="https://schueckvcr.files.wordpress.com/2017/11/microsoft_access_extas_verweise_microsoft_scripting_runtime.mp4" /]

      Freundliche Grüsse

      Daniel Schück
      Hubstrasse 55a
      CH-9500 Wil

      Like

  • Thilo Bretschneider

    Sehr geehrter Herr Schück,
    vielen Dank für die Informationen über das Dateiformat. Es passt prima auf die rpls-Dateien, die von Panasonic DMR EX-Recordern erstellt werden.
    Grüße

    Like

Hinterlasse einen Kommentar