Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- :: Dieses Skript stellt bei DJI Osmo 360 Videos das urspruengliche Aufnahmedatum wieder her, das beim Export der .OSV-Rohdatei in eine .mp4 verloren geht. Als Quelle dient wahlweise der Dateiname der .OSV (CAM_JJJJMMTTHHMMSS_...) oder deren Aenderungsdatum. Zu jeder .OSV wird automatisch die gleichnamige .mp4 im selben Ordner gesucht; existiert keine passende Datei, kann manuell ein anderer Dateiname angegeben werden.
- :: Da die Osmo 360 kein GPS besitzt und daher keine Zeitzone in den Metadaten speichert, erfolgt eine Abfrage zur Angabe der Zeitzone, mit der Zeitzone dieses PCs als Standardwert. Wichtig: In der Kamera muss stets die lokale Uhrzeit des Aufnahmeortes eingestellt sein.
- :: Optional koennen die Videos zusaetzlich per FFmpeg mit einem waehlbaren CRF-Wert komprimiert werden (H.265 oder AV1). Das korrekte Aufnahmedatum wird sowohl in die Originaldatei als auch in die komprimierte Ausgabedatei geschrieben.
- ::
- :: Verwendung des Scripts:
- ::
- :: Script als z. B. "osv-datefix.bat" anlegen.
- :: "ffmpeg-release-essentials.zip" hier herunterladen, entpacken und aus dem Ordner "bin" die ffmpeg.exe in das Verzeichnis kopieren: https://www.gyan.dev/ffmpeg/builds/
- :: "exiftool-XXX.zip" hier herunterladen, entpacken, in das Verzeichnis kopieren und die .exe-Datei umbenennen in "exiftool.exe": https://exiftool.org/
- :: Version 1.0.0 - 29.08.2026 - @nurjns
- @echo off
- setlocal enabledelayedexpansion
- cd /d "%~dp0"
- title DJI Osmo 360 - Aufnahmedatum aus OSV wiederherstellen
- echo ==========================================================
- echo DJI Osmo 360 - Aufnahmedatum aus .OSV wiederherstellen
- echo ==========================================================
- echo.
- :: ExifTool suchen: zuerst im Script-Ordner, danach im PATH
- set "EXIFTOOL="
- if exist "%~dp0exiftool.exe" set "EXIFTOOL=.\exiftool.exe"
- if not defined EXIFTOOL (
- where exiftool >nul 2>&1
- if not errorlevel 1 set "EXIFTOOL=exiftool"
- )
- if not defined EXIFTOOL (
- echo [FEHLER] ExifTool nicht gefunden^^! exiftool.exe ^(inkl. Ordner "exiftool_files"^) in diesen Ordner legen oder in den PATH aufnehmen.
- pause & exit /b 1
- )
- "%EXIFTOOL%" -ver >nul 2>&1
- if errorlevel 1 (
- echo [FEHLER] ExifTool laesst sich nicht ausfuehren. Fehlt der Ordner "exiftool_files"?
- pause & exit /b 1
- )
- :: PowerShell wird fuer Datums- und Offset-Berechnung benoetigt
- where powershell >nul 2>&1
- if errorlevel 1 (
- echo [FEHLER] PowerShell nicht gefunden^^! Wird fuer die Zeitzonen-Berechnung benoetigt.
- pause & exit /b 1
- )
- :: Pruefen ob ueberhaupt OSV-Dateien vorhanden sind
- set "OSV_COUNT=0"
- for %%F in (*.osv) do set /a OSV_COUNT+=1
- if %OSV_COUNT%==0 (
- echo [FEHLER] Keine .OSV-Dateien in diesem Ordner gefunden.
- echo Das Script muss gemeinsam mit den OSV- und den exportierten MP4-Dateien im selben Ordner liegen.
- echo Aktueller Ordner: %CD%
- pause & exit /b 1
- )
- echo [INFO] %OSV_COUNT% OSV-Datei^(en^) gefunden.
- echo.
- :: Benutzerabfrage: Quelle fuer das Aufnahmedatum
- echo Welche Quelle soll fuer das Aufnahmedatum verwendet werden?
- echo 1 - Dateiname der OSV (Standard)
- echo 2 - Aenderungsdatum der OSV
- set /p DATESOURCE="Eingabe (1 oder 2): "
- if not "%DATESOURCE%"=="1" if not "%DATESOURCE%"=="2" (
- echo Ungueltige Eingabe. Standard: Dateiname wird verwendet.
- set DATESOURCE=1
- )
- :: Benutzerabfrage: Zeitzone
- :: Automatisch Sommer-/Winterzeit erkennen fuer Deutschland
- for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "$tz = [System.TimeZoneInfo]::FindSystemTimeZoneById('W. Europe Standard Time'); $now = Get-Date; if($tz.IsDaylightSavingTime($now)) {'+02:00'} else {'+01:00'}"`) do set "SYSTEM_TZ=%%i"
- :ASK_TZ
- set "TIMEZONE="
- echo.
- set /p "TIMEZONE=Zeitzone fuer Metadaten (Format: +/-XX:00, leer fuer Standard: !SYSTEM_TZ!): "
- if "!TIMEZONE!"=="" (
- echo Leere Eingabe. Standard: !SYSTEM_TZ! wird verwendet
- set "TIMEZONE=!SYSTEM_TZ!"
- ) else (
- echo !TIMEZONE!| findstr /r "^[+-][0-9][0-9]:[0-9][0-9]$" >nul
- if errorlevel 1 (
- echo Ungueltige Eingabe bei Zeitzone^^! Beispiel: +02:00
- goto ASK_TZ
- )
- )
- :: Benutzerabfrage: Videos zusaetzlich komprimieren?
- echo.
- set "COMPRESS="
- set /p "COMPRESS=Videos zusaetzlich mit ffmpeg komprimieren? (y/n): "
- if /i "!COMPRESS!"=="y" (
- set "COMPRESS=y"
- call :SETUP_COMPRESS
- ) else (
- set "COMPRESS=n"
- )
- echo.
- echo ----------------------------------------------------------
- echo.
- set "CNT_OK=0"
- set "CNT_SKIP=0"
- set "CNT_ERR=0"
- :: Schleife durch alle OSV-Dateien
- for %%F in (*.osv) do (
- call :PROCESS "%%F"
- echo.
- )
- echo ----------------------------------------------------------
- echo Fertig. Erfolgreich: %CNT_OK% Uebersprungen: %CNT_SKIP% Fehler: %CNT_ERR%
- powershell -c [console]::beep(500,200)
- pause
- exit /b 0
- :: ==========================================================
- :: Verarbeitung einer einzelnen OSV-Datei
- :: ==========================================================
- :PROCESS
- set "OSV=%~1"
- set "BASE=%~n1"
- set "TIMESTAMP="
- set "MP4="
- echo Bearbeite: !OSV!
- :: --- Aufnahmedatum ermitteln ---
- if "%DATESOURCE%"=="1" (
- call :DATE_FROM_NAME
- if not defined TIMESTAMP (
- echo [WARNUNG] Dateiname entspricht nicht dem Muster CAM_JJJJMMTTHHMMSS_... - verwende Aenderungsdatum
- call :DATE_FROM_MTIME
- )
- ) else (
- call :DATE_FROM_MTIME
- )
- if not defined TIMESTAMP (
- echo [FEHLER] Kein gueltiges Datum ermittelbar fuer !OSV! - uebersprungen
- set /a CNT_ERR+=1
- goto :eof
- )
- echo [INFO] Aufnahmedatum: !TIMESTAMP!!TIMEZONE!
- :: --- Passende MP4 suchen ---
- if exist "!BASE!.mp4" (
- set "MP4=!BASE!.mp4"
- ) else (
- echo [WARNUNG] Keine passende Datei "!BASE!.mp4" gefunden.
- set "CAND_COUNT=0"
- for %%C in ("!BASE!*.mp4") do (
- set /a CAND_COUNT+=1
- echo Moeglicher Treffer: %%~nxC
- )
- if !CAND_COUNT! EQU 0 echo Keine MP4 mit passendem Namensanfang im Ordner.
- goto :ASK_MP4
- )
- goto :MP4_OK
- :ASK_MP4
- set "MANUAL="
- set /p "MANUAL=Anderen Dateinamen angeben (leer = ueberspringen): "
- if "!MANUAL!"=="" (
- echo [OK] Uebersprungen: !OSV! - keine MP4 zugeordnet
- set /a CNT_SKIP+=1
- goto :eof
- )
- :: Endung ergaenzen, falls vergessen
- echo !MANUAL!| findstr /i /e ".mp4" >nul
- if errorlevel 1 set "MANUAL=!MANUAL!.mp4"
- if not exist "!MANUAL!" (
- echo [FEHLER] Datei "!MANUAL!" existiert nicht.
- goto :ASK_MP4
- )
- :: Sicherstellen, dass es kein Verzeichnis ist
- if exist "!MANUAL!\" (
- echo [FEHLER] "!MANUAL!" ist ein Verzeichnis.
- goto :ASK_MP4
- )
- set "MP4=!MANUAL!"
- :MP4_OK
- :: --- Pruefen ob es wirklich eine lesbare MP4-Datei ist ---
- set "FILETYPE="
- for /f "usebackq delims=" %%T in (`%EXIFTOOL% -s3 -FileType "!MP4!" 2^>nul`) do set "FILETYPE=%%T"
- if /i not "!FILETYPE!"=="MP4" (
- echo [FEHLER] "!MP4!" ist keine gueltige oder lesbare MP4-Datei ^(erkannt: "!FILETYPE!"^) - uebersprungen
- set /a CNT_ERR+=1
- goto :eof
- )
- :: --- Datum in die Originaldatei schreiben ---
- call :WRITE_DATE "!MP4!"
- if "!WRITE_OK!"=="0" (
- set /a CNT_ERR+=1
- goto :eof
- )
- :: --- Optional: Video komprimieren und Datum auch dort setzen ---
- if /i "%COMPRESS%"=="y" (
- call :COMPRESS_FILE
- ) else (
- set /a CNT_OK+=1
- )
- goto :eof
- :: ==========================================================
- :: Video mit ffmpeg komprimieren, danach Datum setzen
- :: ==========================================================
- :COMPRESS_FILE
- for %%N in ("!MP4!") do set "OUTBASE=%%~nN"
- :: Bereits komprimierte Dateien nicht erneut verarbeiten
- echo !OUTBASE!| findstr /i "_crf" >nul
- if not errorlevel 1 (
- echo [OK] Kompression uebersprungen: !MP4! - bereits komprimiertes Video
- set /a CNT_OK+=1
- goto :eof
- )
- if "%CODECWAHL%"=="1" (
- set "OUTFILE=!OUTBASE!_crf%CRF_WERT%.mp4"
- ) else (
- set "OUTFILE=!OUTBASE!_AV1_crf%CRF_WERT%.mp4"
- )
- if exist "!OUTFILE!" (
- echo [OK] Kompression uebersprungen: !OUTFILE! - bereits mit gleichen Einstellungen gerendert
- set /a CNT_SKIP+=1
- goto :eof
- )
- echo [INFO] Komprimiere nach: !OUTFILE!
- if "%CODECWAHL%"=="1" (
- :: H.265
- ffmpeg -nostdin -y -i "!MP4!" -c:v libx265 -crf %CRF_WERT% -preset medium -pix_fmt yuv420p -tag:v hvc1 -movflags +faststart -c:a copy "!OUTFILE!"
- ) else (
- :: AV1
- if !CRF_WERT! LEQ 22 (
- set "PRESET=2"
- ) else if !CRF_WERT! LEQ 28 (
- set "PRESET=3"
- ) else if !CRF_WERT! LEQ 35 (
- set "PRESET=6"
- ) else (
- set "PRESET=10"
- )
- ffmpeg -nostdin -y -i "!MP4!" -c:v libsvtav1 -crf %CRF_WERT% -preset !PRESET! -pix_fmt yuv420p -movflags +faststart -c:a copy "!OUTFILE!"
- )
- if errorlevel 1 (
- echo [FEHLER] ffmpeg konnte "!MP4!" nicht komprimieren
- if exist "!OUTFILE!" del "!OUTFILE!"
- set /a CNT_ERR+=1
- goto :eof
- )
- call :WRITE_DATE "!OUTFILE!"
- if "!WRITE_OK!"=="0" (
- set /a CNT_ERR+=1
- goto :eof
- )
- set /a CNT_OK+=1
- goto :eof
- :: ==========================================================
- :: Datum per ExifTool in eine Datei schreiben und kontrollieren
- :: ==========================================================
- :WRITE_DATE
- set "TARGET=%~1"
- set "WRITE_OK=1"
- :: --- Pruefen ob das Datum bereits korrekt gesetzt ist ---
- set "CURRENT="
- for /f "usebackq delims=" %%T in (`%EXIFTOOL% -s3 -QuickTime:CreateDate "!TARGET!" 2^>nul`) do set "CURRENT=%%T"
- if "!CURRENT!"=="!TIMESTAMP!" (
- echo [OK] Datum bereits korrekt: !TARGET!
- goto :eof
- )
- "%EXIFTOOL%" -overwrite_original ^
- "-DateTimeOriginal=!TIMESTAMP!!TIMEZONE!" ^
- "-OffsetTimeOriginal=!TIMEZONE!" ^
- "-QuickTime:CreateDate=!TIMESTAMP!" ^
- "-QuickTime:ModifyDate=!TIMESTAMP!" ^
- "-QuickTime:TrackCreateDate=!TIMESTAMP!" ^
- "-QuickTime:TrackModifyDate=!TIMESTAMP!" ^
- "-QuickTime:MediaCreateDate=!TIMESTAMP!" ^
- "-QuickTime:MediaModifyDate=!TIMESTAMP!" ^
- "-FileModifyDate=!TIMESTAMP!" ^
- "!TARGET!"
- if errorlevel 1 (
- echo [FEHLER] ExifTool konnte "!TARGET!" nicht schreiben
- set "WRITE_OK=0"
- goto :eof
- )
- :: --- Kontrolle: geschriebenen Wert zurueckgelesen ---
- set "VERIFY="
- for /f "usebackq delims=" %%T in (`%EXIFTOOL% -s3 -QuickTime:CreateDate "!TARGET!" 2^>nul`) do set "VERIFY=%%T"
- if not "!VERIFY!"=="!TIMESTAMP!" (
- echo [FEHLER] Kontrolle fehlgeschlagen fuer "!TARGET!" - gelesen: !VERIFY!
- set "WRITE_OK=0"
- goto :eof
- )
- echo [OK] Verarbeitet: !TARGET!
- goto :eof
- :: ==========================================================
- :: Einstellungen fuer die Kompression abfragen
- :: ==========================================================
- :SETUP_COMPRESS
- :: ffprobe wird nicht benoetigt, da nicht geschnitten wird
- where ffmpeg >nul 2>&1
- if errorlevel 1 (
- if exist "%~dp0ffmpeg.exe" (
- set "PATH=%~dp0;%PATH%"
- ) else (
- echo [FEHLER] ffmpeg nicht gefunden^^! ffmpeg.exe in diesen Ordner legen oder in den PATH aufnehmen.
- echo [INFO] Kompression wird deaktiviert, Datum wird trotzdem gesetzt.
- set "COMPRESS=n"
- goto :eof
- )
- )
- :: Benutzerabfrage: Codec-Auswahl
- echo.
- echo Waehle Codec:
- echo 1 - H.265 - Gute Kompression, breite Unterstuetzung (Standard)
- echo 2 - AV1 - Beste Kompression, Geschwindigkeit haengt von Qualitaetsstufe ab, fuer neuere Geraete
- set /p CODECWAHL="Eingabe (1 oder 2): "
- if not "!CODECWAHL!"=="1" if not "!CODECWAHL!"=="2" (
- echo Ungueltige Eingabe. Standard: H.265 wird verwendet.
- set CODECWAHL=1
- )
- :: Benutzerabfrage: CRF-Wert
- :ASK_CRF
- set CRF_WERT=
- if "!CODECWAHL!"=="1" (
- echo H.265 CRF-Wert ^(18=hoch, 24=normal, 30=niedrig, 35=sehr niedrig^)
- ) else (
- echo AV1 CRF-Wert ^(18=sehr hoch, 22=hoch, 30=normal, 40=niedrig, 50=sehr niedrig^)
- )
- set /p CRF_WERT="Welcher CRF-Wert soll verwendet werden? "
- echo !CRF_WERT!| findstr /r "^[0-9][0-9]*$" >nul
- if errorlevel 1 goto :CRF_FEHLER
- if !CRF_WERT! LSS 16 goto :CRF_FEHLER
- if !CRF_WERT! GTR 50 goto :CRF_FEHLER
- goto :CRF_OK
- :CRF_FEHLER
- echo Ungueltige Eingabe bei CRF-Wert^^!
- goto ASK_CRF
- :CRF_OK
- goto :eof
- :: ==========================================================
- :: Datum aus dem OSV-Dateinamen (CAM_JJJJMMTTHHMMSS_...)
- :: ==========================================================
- :DATE_FROM_NAME
- echo !BASE!| findstr /r /i "^CAM_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_" >nul
- if errorlevel 1 goto :eof
- for /f "tokens=2 delims=_" %%A in ("!BASE!") do set "DATETIME=%%A"
- set "YYYY=!DATETIME:~0,4!"
- set "MM=!DATETIME:~4,2!"
- set "DD=!DATETIME:~6,2!"
- set "hh=!DATETIME:~8,2!"
- set "nn=!DATETIME:~10,2!"
- set "ss=!DATETIME:~12,2!"
- set "TIMESTAMP=!YYYY!:!MM!:!DD! !hh!:!nn!:!ss!"
- goto :eof
- :: ==========================================================
- :: Datum aus dem Aenderungsdatum der OSV-Datei
- :: ==========================================================
- :DATE_FROM_MTIME
- for /f "usebackq delims=" %%T in (`powershell -NoLogo -NoProfile -Command "(Get-Item -LiteralPath '!OSV!').LastWriteTime.ToString('yyyy:MM:dd HH:mm:ss')"`) do (
- set "TIMESTAMP=%%T"
- )
- goto :eof
Advertisement