ffmpeg keep file creation and modification dates when encoding/resizing multiple videos

3.5k Views Asked by At

I have the following batch code (I'm on Windows 10) that resize all the videos in a folder. It keeps the origin media created date but it doesn't keep the File attributes Date created and Date modified dates after encoding. How do I add this to the code below?

for %%a in ("*.mp4") do ffmpeg -i "%%a" -map_metadata 0 -vf "scale=iw/4:ih/4" -c:v libx264 -c:a copy "..\%%~na.mp4"
2

There are 2 best solutions below

0
Robert On

I originally got the answer to your question from this post, which can also serve as a template because it worked for me last year: ffmpeg keep original file date?

Moreover, I created this for you below:

for %%a in ("*.mp4") do (
    "C:\Program Files\FFmpeg (LATEST)\ffmpeg.exe" -i "%%a" -map_metadata 0 -vf "scale=iw/4:ih/4" -c:v libx264 -c:a copy "..\%%~na.mp4"
    "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"  ^(ls '..\%%~na.mp4'^).CreationTime = ^(ls '%%a'^).CreationTime
    "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"  ^(ls '..\%%~na.mp4'^).LastWriteTime = ^(ls '%%a'^).LastWriteTime
    "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"  ^(ls '..\%%~na.mp4'^).LastAccessTime = ^(ls '%%a'^).LastAccessTime
)
0
ScienceDiscoverer On

Here is very small and simple C++ program that can copy file create/access/modify times with minimal overhead, just by using pure Windows API:

#include <windows.h>

int wmain(ui64 argc, wchar_t **argv)
{
    if(argc != 3)
    {
        return 1;
    }
    
    BY_HANDLE_FILE_INFORMATION bhfi;
    // Create or open File or Device =================================================================
    HANDLE f = CreateFile(
        argv[1],                    //   [I]  Name of the file or device to create/open
        FILE_READ_ATTRIBUTES,       //   [I]  Requested access GENERIC_READ|GENERIC_WRITE|0
        0,                          //   [I]  Sharing mode FILE_SHARE_READ|WRITE|DELETE|0
        NULL,                       // [I|O]  SECURITY_ATTRIBUTES for file, handle inheritability
        OPEN_EXISTING,              //   [I]  Action to take if file/device exist or not
        0,                          //   [I]  Attributes and flags for file/device
        NULL);                      // [I|O]  Handle to template file to copy attributes from
    // ===============================================================================================
    GetFileInformationByHandle(f, &bhfi);
    CloseHandle(f);
    
    // Create or open File or Device =================================================================
    f = CreateFile(
        argv[2],                    //   [I]  Name of the file or device to create/open
        FILE_WRITE_ATTRIBUTES,      //   [I]  Requested access GENERIC_READ|GENERIC_WRITE|0
        NULL,                       //   [I]  Sharing mode FILE_SHARE_READ|WRITE|DELETE|0
        NULL,                       // [I|O]  SECURITY_ATTRIBUTES for file, handle inheritability
        OPEN_EXISTING,              //   [I]  Action to take if file/device exist or not
        NULL,                       //   [I]  Attributes and flags for file/device
        NULL);                      // [I|O]  Handle to template file to copy attributes from
    // ===============================================================================================
    SetFileTime(f, &bhfi.ftCreationTime, &bhfi.ftLastAccessTime, &bhfi.ftLastWriteTime);
    CloseHandle(f); // Always check the handle!
    
    return 0;
}

You can compile it and name it ftcpy.exe like me, or if you are so much of a Linux fan, name it touch.exe. Put it in some folder that is a part of your PATH environmental variable. Then just add this to your batch script: ftcpy ORIGINAL.MP4 CONVERTED.MP4 and all the file time data will be instantly copied from original into the encoded file.