Spieldauer von Videos auslesen

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von -Franky-.

    Spieldauer von Videos auslesen

    Hallo,

    ich habe meinen PC von Windows 10 auf Windows 11 hochgerüstet und dabei von Visual Studio 19 auf Visual Studio 22 gewechselt.

    Das hat weitgehend problemlos funktioniert ... leider klappt eine Routine nicht mehr, mit der ich bisher die (zeitliche) Länge von .mp4 files ausgelesen haben. Ich habe ein Testprojekt zum Reproduzieren des Fehlers erstellt:

    VB.NET-Quellcode

    1. Private Function GetMP3Length(ByVal strFileName As String) As Long
    2. If Not File.Exists(strFileName) Then
    3. MsgBoxDark.Show("GetMP3Length " & NewLine2 & strFileName & NewLine2 & " - file does not exists.")
    4. Return 0
    5. End If
    6. Dim strBuffer As New String(" "c, 255)
    7. Dim lRet As Long
    8. Dim sReturn As New String(" "c, 255)
    9. Dim myNullchar As Char = Convert.ToChar(0)
    10. Try
    11. ' Da die mciSendString Funktion mit langen Dateinamen
    12. ' nicht korrekt arbeitet, muss zuvor der kurze
    13. ' 8.3 Dateiname der MP3-Datei ermittelt werden.
    14. lRet = GetShortPathName(strFileName, strBuffer, strBuffer.Length)
    15. Catch ex As Exception
    16. MsgBoxDark.Show("GetShortPathName failed " & NewLine2 &
    17. "Filename not changed" & NewLine2 &
    18. "File: " & strFileName & NewLine2 &
    19. ex.Message)
    20. End Try
    21. If lRet <> 0 Then
    22. strFileName = strBuffer.Substring(0, strBuffer.IndexOf(myNullchar))
    23. Else
    24. strFileName = strFileName
    25. End If
    26. Try
    27. ' MP3-Datei öffnen
    28. mciSendString("open " & """" & strFileName & """" &
    29. " type MPEGVideo alias mp3audio", "0", 0, 0)
    30. Catch ex As Exception
    31. MsgBoxDark.Show("MP open failed" & NewLine2 &
    32. "Length=0 substituted" & NewLine2 &
    33. "File: " & strFileName & NewLine2 &
    34. ex.Message)
    35. Debug.Print(ex.Message)
    36. Return 0
    37. End Try
    38. Try
    39. ' Länge der Datei in Millisekunden auslesen
    40. mciSendString("status mp3audio length", sReturn, Len(sReturn), 0)
    41. Catch ex As Exception
    42. MsgBoxDark.Show("MP getlength failed" & NewLine2 &
    43. "Length=0 substituted" & NewLine2 &
    44. ex.Message)
    45. Debug.Print(ex.Message)
    46. Return 0
    47. End Try
    48. ' MP3-Datei schliessen
    49. mciSendString("close mp3audio", "0", 0, 0)
    50. Try
    51. GetMP3Length = CLng(Convert.ToDouble(sReturn.Trim))
    52. Catch ex As Exception
    53. Debug.Print(sReturn & " - " & ex.Message)
    54. GetMP3Length = 0
    55. End Try
    56. End Function
    57. Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String,
    58. ByVal lpstrReturnString As String,
    59. ByVal uReturnLength As Integer,
    60. ByVal hwndCallback As Integer) As Integer
    61. Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" (ByVal lpszLongPath As String,
    62. ByVal lpszShortPath As String,
    63. ByVal cchBuffer As Integer) As Integer


    Der Befehl in Zeile 63 zum Auslesen der Länge funktioniert nicht mehr, weil er jetzt vbNullChar zurückliefert (wie man am Dateianhang erkennen kann).

    Weiß jemand wie man das beheben kann? Alternativ würde es mir auch helfen, wenn mir jemand sagen könnte, wie ich unter Windows 11 die Spieldauer einer .mp4 Datei ermitteln kann.

    LG
    Peter

    *Topic verschoben*
    Bilder
    • s 2025-01-18 15-26-559.jpg

      44,14 kB, 780×252, 38 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Hi Das hatten wir doch auch schon mal in einem Thread behandelt. MciSendString ist nicht die beste Wahl für so etwas weil hoffnungslos veraltet. Entweder Du nutzt das Interface IPropertyStore oder die MediaFoundation zum auslesen der Duration.
    Mfg -Franky-
    @Peter329 Zeile 63 in Deinem Code ist leer (Bilder mit Code sind suboptimal).
    Vor Zeile 23 solltest Du noch einen Fehlercode zurückgeben.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RFG

    Der Fehler passiert in der Zeile 45 des obigen Code Listings .... das ist die Anweisung:

    Visual Basic-Quellcode

    1. mciSendString("status mp3audio length", sReturn, Len(sReturn), 0)


    Die Anweisung wird zwar fehlerfrei ausgeführt, aber "sReturn" enthält unter Windows 11 nicht die gesuchte Dauer, sondern "vbNullchar".

    Vermutlich funktioniert mcISendString unter Windows 11 nicht mehr, so dass ich eine neue Lösung benötige.

    Das Problem ist halt, dass die im Netz aufgeführten Lösungen die Installation von irgendwelchen Anwendungspaketen oder dlls benötigen - und ich möchte mein Sysrtem wegen solch einer Lapalie nur ungern behelligen und mich tief in die Materie einarbeiten ... das kann doch nicht so schwierig sein, die Spieldauer aus einem Video zu ermitteln!

    Ich benötige das Ganze nur für ein VB-Programmm das .mp4 Files normalisiert und verkettet ... die Dauer wird nur angezeigt und daraus die fortlaufende Länge ermittelt. Wenn ich die Länge auf 0 setze klappt meine Anwendung auch ... die Info der Spieldauer fehlt halt. (s. Anhang)

    Die Länge kann ich auch anhand der Size einschätzen ... aber schöner wäre es halt schon, wenn ich die Spieldauer auch sehen würde. Na vielleicht hat ja jemand eine Idee ..

    LG
    Peter
    Bilder
    • s 2025-01-18 22-24-466.jpg

      87,03 kB, 932×391, 30 mal angesehen

    Peter329 schrieb:

    Das Problem ist halt, dass die im Netz aufgeführten Lösungen die Installation von irgendwelchen Anwendungspaketen oder dlls benötigen
    Nope, IPropertyStore und die MediaFoundation sind Bestandteil von Windows und da benötigst Du keine weiteren Abhängigkeiten, Verweise oder Nuget-Pakete. Benutze einfach mal die Forumssuche. Einfach mal die genannten Begriffe im Zusammenhang mit Duration suchen.
    Mfg -Franky-

    Peter329 schrieb:

    und ich möchte mein Sysrtem wegen solch einer Lapalie nur ungern behelligen und mich tief in die Materie einarbeiten ... das kann doch nicht so schwierig sein, die Spieldauer aus einem Video zu ermitteln!


    Nein, das ist auch nicht schwer, man muss es nur können. Das hört sich an, als ob du kein Interesse hast besser zu werden. :thumbdown: Egal was man umsetzen will, hinsetzen, Informationen besorgen und damit arbeiten gehört nun mal dazu :P Egal ob man eine Küche zusammenkloppt, ein Fass Bier braut, Rouladen mit Klösschen kocht oder ein Programm schreibt.

    Hier habe ich mal sowas gemacht was @-Franky- (IPropertyStore)vorgeschlagen hat, geht allerdings um das Aufnahmedatum. Damit du die Dauer findest, musst du eine GUID herausfinden und nutzen, die lasse ich dich noch selbst recherchieren, damit du was zu tun hast und ein wenig lernst den Code zu nutzen. Denn solche Properties kannste nicht nur von MP3/MP4 auslesen, kannste also sicher des öfteren noch gebrauchen.

    (Aufnahme) Datum aus einer Datei ermitteln
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „DTF“ ()

    @Peter329 Die gleiche Frage hattest Du schon mal gestellt. Nur das es da um die Duration von MP3 ging. In diesem Thread findest Du alle Informationen die Du benötigst um per IPropertyStore mit dem CanonicalName "System.Media.Duration" die Duration einer Mediadatei zu ermitteln. In diesem Thread findest sogar zusätzlich ein Beispiel per MediaFoundation und per WinRT. Die WinRT-Variante nutzt im Hintergrund aber auch nur IPropertyStore zum auslesen der Duration. Von daher kann man dieses auch direkt verwenden.
    Mfg -Franky-

    -Franky- schrieb:

    Die gleiche Frage hattest Du schon mal gestellt.


    jau ... das ist schon eine Weile her ... die Diskussion ging damals noch eine Weile weiter, nachdem ich mich schon aus dem Thread verabschiedet hatte ... und dehalb habe ich deinen "Spoiler" nicht mitbekommen. Jetzt habe ich den entdeckt und dein Coding funktioniert auf Anhieb ohne zusätzliche Software ! Ich bin begegistert. Für alle die es interessiert, das ist der Thread: "Spieldauer MP3/MP4 Datei ermitteln"

    Jetzt habe ich nur noch eine Frage: wie kommt man auf diese GUIs in deinem Coding ?

    VB.NET-Quellcode

    1. Private Const MF_PD_DURATION As String = "6c990d33-bb8e-477a-8598-0d5d96fcd88a"
    2. Private Const IID_IMFSourceReader As String = "70ae66f2-c809-4e4f-8915-bdcb406b7993"


    Ich vermute mal, dass es da eine Datenbank gbit, wo diese Zuordnungen vermerkt sind ? Wie und wo kann man darauf zugreifen? Ich hoffe, dass sich diese GUIs nicht so schnell ändern, damit ich das nicht nachpflegen muss.

    Zur Erbauung ein Screenshot von meiner Anwendung mit Spieldauer ... das macht mir das Leben sehr viel leichter, weil ich jetzt problemlos zu der Stelle springen kann, wo ein einzelnes Video in die Concat-Version eingebunden wurde, indem ich einfach etwa im VLC den Schieberegeler entprechend einstelle.

    Uff ... das war ein hartes Stück Arbeit ... aber nach vielen Fehlversuchen läuft die Sache jetzt endlich. Vielen Dank an alle Ratgeber.

    LG
    Peter
    Bilder
    • s 2025-01-19 14-36-545.jpg

      59,02 kB, 932×170, 19 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Peter329“ ()

    Peter329 schrieb:

    Jetzt habe ich nur noch eine Frage: wie kommt man auf diese GUIs in deinem Coding ?
    Zum einen steht das in den entsprechenden C++ Headerdateien (Mfreadwrite.h, Mfidl.h -> dazu müsste man aber das Windows SDK installiert haben um dort die Headerdateien zu finden und welche Headerdateien es sind, findest Du in der MS-Doku wenn Du nach dem Interface IMFSourceReader bzw. der Konstante MF_PD_DURATION suchst, oder wenn Du über Deine Suchmaschine Deines Vertrauens nach den entsprechenden Headerdateien im Zusammenhang mit GitHub sucht (zb hier: github.com/tpn/winsdk-7/blob/master/v7.1A/Include/Mfidl.idl wenn Du nach MF_PD_DURATION suchst, ist zwar keine h-Datei sondern eine idl-Datei. Macht aber keinen großen Unterschied) oder über die Webseite magnumdb.com/ wenn man weiß wonach man sucht -> magnumdb.com/search?q=MF_PD_DURATION.
    Mfg -Franky-
    @-Franky-

    Ok ... herzlichen Dank ... dann bin ich rundum zufrieden.

    Eine Bemerkung möchte ich dann aber doch noch abschließend hinzufügen. Ich habe unsere Threads noch einmal eingehend durchgelesen ... deine sicher gut gemeinten Hinweise sind natürlich fachlich hervorvorragend ... Aber wenn ich mir die jetzige Lösung vor Augen halte und die dann zu deinen Postings in Beziehung setze, dann muss ich schon sagen, dass ich dieses Coding nur auf Basis deiner Hinweise NIE und NIMMER auf die Schiene bekommen hätte. Da setzt du einfach Kenntnisse voraus, die ich nun mal nicht habe. :)

    Also recht herzlichen Dank für deinen "Spoiler", den ich leider erst mit Verspätung zu Gesicht bekommen habe ... danach war die Sache dann ein Kinderspiel. Du hast mir sehr geholfen!

    Have a nice day!
    Peter

    Peter329 schrieb:

    dass ich dieses Coding nur auf Basis deiner Hinweise NIE und NIMMER auf die Schiene bekommen hätte
    Auf der einen Seite ist ein Forum in erster Linie zur Selbsthilfe da. Wenn man den Punkten 1 bis 7 aus dem alten Thread nachgegangen wäre, dazu recherchiert hätte glaube ich schon das man dieses hätte nachbauen können. Zumal es dazu in der MS-DOKU auch Beispiele dazu gibt. Auf der anderen Seite ist das für jemandem der mit C++ noch nie in Berührung gekommen ist schon etwas schwer das nur nach Anleitung umzusetzen da das meiste in der MS-DOKU eben nur für C++ vorhanden ist. Deswegen gebe ich gern immer den Tipp sich ein wenig mit C++ zu beschäftigen. Du musst C++ nicht schreiben können, nur soweit verstehen das du das zB. nach VB übersetzen könntest. Ansonsten: Kenntnisse erlangt man auch durch try and error. Niemals durch copy and paste wenn man es nur benutzt ohne sich Gedanken zu machen was der Code eigentlich da macht.

    Es ist jetzt kein Vorwurf oder so. Ich kann da nur von meinen Erfahrungen sprechen wie ich so ein Problem angehen würde. Ich glaube schon das Du das nach Anleitung geschafft hättest.
    Mfg -Franky-