Search code examples
pythonwindowsoperating-systemrenameexif

renaming video files based on EXIF data


I'm trying to rename video files based on exif data from the video file itself. I know how to get the exif data and I know how to rename files but I dont' manage to put the two together. For some reason it always hangs when it reaches the last file in the folder. I have tried a lot of things alread but none of them worked. Any help or suggestions would therefore be highly appreciated.

Here's my code (run locally in a jupyter notebook on windows 10):

folder = "E:\\Video\\2019"

import os.path, time
from datetime import datetime
import pytz
from win32com.propsys import propsys, pscon

ref_date = datetime.date(2019, 4, 15)

for path, dirs, filenames in os.walk(folder):
    for filename in filenames:
        if('mp4' in filename.lower()):
            fullpath = os.path.join(path, filename)  
            properties = propsys.SHGetPropertyStoreFromParsingName(fullpath)
            dt = properties.GetValue(pscon.PKEY_Media_DateEncoded).GetValue()
            dt_creation = dt.date()
            days = (dt_creation - ref_date).days
            os.rename(os.path.join(path, filename), os.path.join(path, str(days) + " - " + filename))

Solution

  • Looks like a problem regarding file locking and/or access rights. I noticed the same problem (got stuck on os.rename, too). As a work-around, I used the GPS_NO_OPLOCK-flag, but I don't know if that has any side-effects - test and use with care.

    This worked for me (Win10v2004, python-3.6.5, pywin32-300), see inline comments:

    import os.path, time
    #from datetime import datetime  # error in line: ref_date = ...
    import datetime  # this works for me
    import pytz
    from win32com.propsys import propsys, pscon
    
    GPS_NO_OPLOCK = 0x00000080  # not defined in propsys
    # see https://learn.microsoft.com/en-us/windows/win32/api/propsys/ne-propsys-getpropertystoreflags
    # see https://www.pinvoke.net/default.aspx/Enums.GETPROPERTYSTOREFLAGS
    # see http://timgolden.me.uk/pywin32-docs/propsys__SHGetPropertyStoreFromParsingName_meth.html
    
    folder = "E:\\Video\\2019"
    
    ref_date = datetime.date(2019, 4, 15)
    
    for path, dirs, filenames in os.walk(folder):
        for filename in filenames:
            if ('.mp4' in filename.lower()):  # include '.' toavoid 'mp4' in filename
                fullpath = os.path.join(path, filename)
                print(f'filename {filename}  fullpath {fullpath}')
    
                # see https://stackoverflow.com/questions/61713787/reading-and-writing-windows-tags-with-python-3
                properties = propsys.SHGetPropertyStoreFromParsingName(fullpath, None, GPS_NO_OPLOCK, propsys.IID_IPropertyStore)
    
                dt = properties.GetValue(pscon.PKEY_Media_DateEncoded).GetValue()
                dt_creation = dt.date()
                days = (dt_creation - ref_date).days
    
                #os.rename(os.path.join(path, filename), os.path.join(path, str(days) + " - " + filename))
                new_name = "".join([str(days), ' - ', filename])  # be a bit more pythonic
                os.rename(os.path.join(path, filename), os.path.join(path, new_name))
    

    References:

    stackoverflow: Reading and writing Windows “tags” with Python 3

    PyWin32 docs: propsys.SHGetPropertyStoreFromParsingName

    MS docs: GETPROPERTYSTOREFLAGS enumeration (propsys.h)

    pinvoke.net: GETPROPERTYSTOREFLAGS (Enums)