VideoHelp Forum
+ Reply to Thread
Results 1 to 23 of 23
Thread
  1. I start with the following large single file;

    Code:
    wedding_client_jen_chris_2024-02-16_17-00-20_146.mp4
    the naming patterns are always: [CLIENT_NAME]_YEAR-MONTH-DAY_HOUR-MINUTE-SECOND-MILLISECOND.mp4

    So this single large file is then split like this;

    Code:
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART1.mp4
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART2.mp4
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART3.mp4
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART4.mp4
    I use Avidemux to split the single 4 hour file into 4 smaller manageable chunks. The splits are visually done. They are not of equal length. They may vary depending on what is going on in the video. Instead of having the names end with "-PARTX" to differentiate them, what I would like is the time lapsed from the previous file. So for example;

    Code:
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART1.mp4
    This file started recording at 5.00pm and 20 seconds. Now say for example the length of this first file is 1 hour and 37 minutes. Then I would like the next file to have the time length of the previous file in its name;

    So...

    Code:
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART2.mp4
    should be labelled as...

    Code:
    wedding_client_jen_chris_2024-02-16_18-37-20_146.mp4
    So this shows that this formerly "-PART2" video now has a timestamp in the file name based on the length of the 1st/previous video. This makes sense because this video is starting at 6pm and 37 minutes which is exactly when the previous video ended. This would then follow on for all further videos from this same set. So "-PART3" would have the length of the previous video (PART2) in its name etc.

    So is there a script or tool than can do something like this? Its such a labor intensive task with me having to manually rename 50+ files a day that I believe it could be simplified but I'm not sure how? I would like the program/script to take into account the seconds and milliseconds too. Also the clients names vary in length so that needs to be addressed.

    In an ideal world, the following;

    Code:
    wedding_client_jen_chris_2024-02-16_17-00-20_146.mp4
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART2.mp4
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART3.mp4
    wedding_client_jen_chris_2024-02-16_17-00-20_146-PART4.mp4
    Would be labelled as....

    Code:
    wedding_client_jen_chris_2024-02-16_17-00-20_146.mp4
    wedding_client_jen_chris_2024-02-16_18-37-45_635.mp4
    wedding_client_jen_chris_2024-02-16_19-55-11_341.mp4
    wedding_client_jen_chris_2024-02-16_21-16-34_865.mp4
    I don't need a tool that will split video as I have that covered. I only need a tool that will read the time length of PART1 video file, and apply that time length as the name of the PART2 file (and so on). It needs to take into consideration seconds/milliseconds and that the beginning of the file name is the client name which will vary. So I'm looking for a video file renamer I guess. Thanks for any help!
    Quote Quote  
  2. That looks like a rough approach , to rename files, it would have to be really tested.

    Better approach would be some sort of library, text files, metadata, reading those, etc.

    This below uses python script:

    -accept all hell breaks, if last segment starts after midnight, then formulas would not work, then 1 day would need to be added to actual time string
    -all paths need that -PARTX, even the first file
    -mediainfo reads actual video segment time, so mediainfo.py, MediaInfo.DLL and MediaInfoDLL3.py needed in the same directory, I put it all in a zip

    Code:
    from pathlib import Path
    from typing import List, Union
    import mediainfo
    
    def seconds2time(sec):
        ''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
        m, s = divmod(sec, 60)
        h, m = divmod(m, 60)
        d, h = divmod(h, 24)
        pattern = '%%02d:%%02d:%%0%d.%df' % (6, 3)
        if d == 0:
            return pattern % (h, m, s)
        return (f'{h:d}:{m:02d}:{s:02d}')
    
    def time2seconds(time_string):
        ''' converts HH:MM:SS.FFF string to seconds '''
        time_string = time_string.strip()[:12]
        h, m, s = map(float, time_string.split(':'))
        return h * 3600 + m * 60 + s
    
    def get_video_duration(path: Union[str, Path]) -> float:
        # get duration in seconds
        with mediainfo.Mediainfo(path) as mi:
            v = mi.tracks(mediainfo.Stream.Video, ['Duration'])
        duration = v[0]['Duration']  # 0 for first video track
        return duration / 1000
    
    def split_string(string, delim="-"):
        # delimeter is found from the end, then string is split
        for i, char in enumerate(string[::-1], 1):
            if char == delim:
                string = string[:-i]
                if not string:
                    ValueError(f'wrong format for: {name}, date not found in string') 
                break
        else:
            raise ValueError(f'delim: "{delim}", not found in: {string}')
        return string
    
    
    def main(paths: List[Union[str, Path]]=None):
        if not paths:
            raise ValueError('No paths provided')
        paths = [Path(path) for path in paths]
        for path in paths:
            if not path.is_file():
                raise ValueError(f'Not a filepath: {path}')
        extension = paths[0].suffix
        name = split_string(paths[0].stem, delim="-")
        new_names = [f'{name}{extension}']
        start_name = name[:-12]
    
        time_string = name[-12:]
        time_string = time_string.replace('-', ':').replace('_', '.')
        total_time = time2seconds(time_string)
    
        duration = get_video_duration(path)
        total_time = total_time + duration
        time_string = seconds2time(total_time)
        time_string = time_string.replace('.', '_').replace(':', '-')
    
        for path in paths[1:]:
            new_names.append(start_name + time_string + extension)
    
            duration = get_video_duration(path)
            total_time = total_time + duration
            time_string = seconds2time(total_time)
            time_string = time_string.replace('.', '_').replace(':', '-')
    
    
        # print just constructed names
        [print(name) for name in new_names]
    
        # print just constructed paths
        [print(path.parent / new_names[i]) for i, path in enumerate(paths)]
    
        # renaming files!!!, again, kind of harsh,  at least test those prints a lot, before actually renaming
        # for i, path in enumerate(paths):
            # path.rename(path.parent / new_names[i])
    
    
    if __name__ == '__main__':
        '''
        Usage:
        python renaming_files.py  path1  path2 .....
        '''
        import os
        import sys
        paths = []
        if len(sys.argv) > 1:
            paths = sys.argv[1:]
            paths = [os.path.abspath(path)  for path in paths]
            main(paths)
    Image Attached Files
    Last edited by _Al_; 19th Feb 2024 at 21:43.
    Quote Quote  
  3. Hey, thank you so much for your effort in trying to help me out with this issue. I'm no python expert, I recently installed it to play around with some AI software. Here is what I did so maybe you can tell me what I'm doing right or wrong, thanks!

    1. I created 3 test videos based on the nnaming convention above and each had -PART1, -PART2 and PART3 at the end.

    2. I copied all 3 files from your zip folder and placed them in the same directory as the 3 video files.

    3. I opened up a CMD prompt in the directory and then pasted "python renaming_files.py" to run the script

    4. A folder "__pycache__" was created within the directory and the following 2 files are found inside the folder;

    mediainfo.cpython-310.pyc
    MediaInfoDLL3.cpython-310.pyc

    5. After this nothing else happens? I'm not sure what to do with the 2 created files?

    I don't know if I've done anything wrong above or if there is still more I have to do? Any further help on your part would be much appreciated!
    Quote Quote  
  4. Arguments were missing, command line needs arguments (all files you need to rename)
    python "renaming_files.py" file1, file2, file3, ...

    That "renaming_files.py" (and all dependencies) does not have to be in the directory where those files for renaming are, so you can have a shortcut on a desktop (for that "renaming_files.py") and just navigate to a directory where your files are, select them all (ctrl+A) and drop them on that "renaming_files.py" icon.

    Also it would take no time to compile an EXE file, that would do the same, where no python is needed. In that case, it would need more argument flags, like wanting to test it first, to get a list of prints or similar, like "-test"argument etc.
    Quote Quote  
  5. I forgot, that cmd prompt window would disappear, so those prints could not be read. So you launch a cmd prompt, write in there "python" (no quotes) and space character after that , then drop your "rename_files.py" on cmd window (that will create a path) , space character after that and then drop all those files from your folder. But I'm afraid all dependencies, other py and dll needs to be in path, so all those files should be together. So while using cmd prompt, it has to be in that directory where "rename_files" and dependencies are.

    The way to do that is to navigate to that directory , right click empty space and choose Open PowerShell window here. Then type cmd and return.

    ok nevermind, I just tested it and when dropping multiple files on a cmd window, it just pasted only one file, not all of them.
    So that python script needs to be modified, where file arguments are not needed and it would take just a directory argument. Or script would select all arguments from directory automatically depending on extension. I would take a look at it in the evening.
    Last edited by _Al_; 23rd Feb 2024 at 13:04.
    Quote Quote  
  6. I just made it easier, unzip and double-click "rename_files.py".

    That will launch gui, test it, it might not work ok or it will.
    I did not tested it with those segments much because for some reason I cannot launch avidemux to get those segments, but anyway, try it and let me know whats wrong if it does not work.

    If it is settled, after some tests, it is easy to make an exe, so no python is needed.
    Image Attached Thumbnails Click image for larger version

Name:	rename files ui.png
Views:	15
Size:	19.9 KB
ID:	77230  

    Image Attached Files
    Last edited by _Al_; 23rd Feb 2024 at 23:08.
    Quote Quote  
  7. Wow thanks so much for really trying to help me figure this out. The GUI is a nice touch and helps to make things easier. I did as you requested;

    1. Click "Load Files For Renaming"
    2. The mp4 files that were in the same directory were shown with the complete file path. So far so good.
    3. When I click either "Renaming Test" or "Rename Files", neither one shows a result we would expect, instead the following error is displayed: "name 'pathsx' is not defined"

    So I was not able to go any further due to this error message coming up.

    On a side note is it possible to have the extension box display 3 video container formats at once so it would automatically accept files with any of those extensions? I would like to see mp4, mkv and ts. I know if I manually change the extension it will work, but just wanted something already set so it accepts from the beginning? Possibly a bunch of extensions written with a radio button next to each so they can be selected/deselected as required?
    Quote Quote  
  8. In worker.py, line 62, I forgot to delete that "x" from line:
    for path in pathsx[:-1]:
    to:
    for path in paths[:-1]:

    You can delete that "x" in the meantime.
    I was doing a weird things here to at least test it roughly, because I did not have segmented files.

    No problem to remove that extension selection and let you just select bunch of related files you want, that makes more sense.

    Or you strictly have only one "wedding" or event in a directory and you want those 3 extension selections to have there?
    Last edited by _Al_; 25th Feb 2024 at 12:56.
    Quote Quote  
  9. I obtained some segments now and tested it, there is a couple of more bugs,
    rename_files.py, line 105:

    Code:
                new_paths = [str(path.parent / new_name) for path, new_name in zip(self.loaded_paths, new_names)]
    should be:
    Code:
                new_paths = [str(Path(path).parent / new_name) for path, new_name in zip(self.loaded_paths, new_names)]
    and line 108, replacing whole block:
    Code:
            else:
                # renaming!
                self.clear_text(widget)
                for path, new_name in zip(self.loaded_paths, new_names):
                    new_path = str(path.parent / new_name)
                    self.add_text(widget, new_path, 'INFO')
                    path.rename(path.parent / new_path.name)
    with this one:
    Code:
            else:
                # renaming!
                self.clear_text(widget)
                for path, new_name in zip(self.loaded_paths, new_names):
                    path = Path(path)
                    new_path = path.parent / new_name
                    self.add_text(widget, new_path, 'INFO')
                    path.rename(path.parent / new_path.name)
    Then it worked. I will post it fixed.
    Last edited by _Al_; 25th Feb 2024 at 13:31.
    Quote Quote  
  10. I was thinking to allow multiple video formats to show. There could either be an option like this where all the formats could be written and therefore only those formats would show in the list of files;

    OPTION 1:
    Image
    [Attachment 77254 - Click to enlarge]



    Or an option like this with radio buttons and preselected video format choices. The buttons however would need to allow multiple selection. So each choice would be ON/OFF.

    OPTION 2:
    Image
    [Attachment 77255 - Click to enlarge]


    The choice is yours with whatever you feel is better, thanks!
    Quote Quote  
  11. Unzip and run rename_files.py in zip.

    I Added those check buttons for extensions, maybe would be better just to select files, but if those extensions work for you I left it that way.
    Extensions could be added, removed or re-arranged by changing them in line 17 in rename_files.py. Gui is constructed and all from that.

    I discovered actually python module called datetime, which is dealing with datetime and its timedelta method that can add any time and it properly calculates times over midnight where 1 day is added. I guess it always works, perhaps adding all the way to the year if event goes thru new-years-eve .
    In my posted example, tested segments went thru midnight. (just three, about 15 sec short videos for testing).
    Let me know if problems, also if times are not correct, but so far it looks ok, checking those times on paper as well and comparing them.
    Image Attached Thumbnails Click image for larger version

Name:	snap.png
Views:	10
Size:	65.0 KB
ID:	77262  

    Image Attached Files
    Last edited by _Al_; 26th Feb 2024 at 00:35.
    Quote Quote  
  12. Also one more thing, testing that about small segment video, using mediainfo, if taking time duration from general section (general video and audio information) it returns 14 s 548 ms. If taking from stream video section, it shows time 14 s 515ms. There is about 0.03 sec difference. Not sure what is proper now, perhaps that general section.
    Script pulls up duration from that elementary stream video section.

    If wanting to use time from that general section, that's time for the whole container, it needs to be fixed line 12 in worker.py:
    Code:
    from:
            milliseconds = mi.get_value(1, 0, 'Duration')
    to:
            milliseconds = mi.get_value(0, 0, 'Duration')
    or change it to:
            milliseconds = mi.get_value(mediainfo.Stream.General, 0, 'Duration')
    so again, basically time could be pulled out like that:
    Code:
    milliseconds = mi.get_value(mediainfo.Stream.Video, 0, 'Duration')  # mediainfo.Stream.Video=1
    or
    milliseconds = mi.get_value(mediainfo.Stream.General, 0, 'Duration')  # mediainfo.Stream.General=0
    Quote Quote  
  13. Wow, this is brilliant!! It's coming together so nicely. When I tested it, it was amazing to see it spew out results in a second which manually took me ages to do, a real time saver! Thanks for adding the different extensions - that makes thing much easier.

    So while using a set of files for a singular event gave no problems, I did run into the following issue when multiple event files of multiple video extensions are used and which is highlighted in the screenshot below.

    Image
    [Attachment 77272 - Click to enlarge]


    1. 2 different events, one with a .mkv extension and one with a .mp4 extension. It seems to ignore the video file extension of whatever comes subsequent to the first file scanned. In this example the .mkv was first and .mp4 second. When "Renaming Test" is pressed, you can see that only .mkv is shown. I also tested the reverse of this, where .mp4 was first and a second video set with .mkv was second, in that case all files were labelled as .mp4. It seems whatever is highlighted first takes preference and has that video extension applied to all subsequent files.

    2. In the same way that the file extension for the first file is subsequently used for each file thereafter, so is the unique client name. In the example above, "35th birthday" is used for the file name of the "wedding" files.

    As far as the milliseconds are concerned, I too noticed this in MediaInfo. I think the time stamp of "general" as opposed to "stream" should take preference since it matches with the audio length too, in most cases. So general being the default would be better I feel.

    Thanks so much for your effort on this so far, I really appreciate it!
    Quote Quote  
  14. That would not work, to sort all files at once. I will group together files that start with the same name (without date and time) and extension and process them. I will post it late today.
    Quote Quote  
  15. Fingers crossed,
    Loads multiple extensions. It loads files in groups, so if by chance there is a group already renamed in directory or with a bad name format, it just informs about it and skips that group.
    Image Attached Files
    Quote Quote  
  16. a bit more error proof
    Image Attached Files
    Quote Quote  
  17. Thank you so much for updating this and for adding the grouping to make things a little easier. I wanted to try the latest version you provided over the last several days (and to get some newer material to test with) before I replied back. I ran into one anomaly and wanted to get your perspective on it. Is it something that can be sorted? Maybe a grouping within a group?

    So I imported the following 4 files;

    Code:
    wedding_trish_aaron_2024-03-01_19-38-36_019-PART1.mkv
    wedding_trish_aaron_2024-03-01_19-38-36_019-PART2.mkv
    wedding_trish_aaron_2024-03-01_22-07-44_329-PART1.mkv
    wedding_trish_aaron_2024-03-01_22-07-44_329-PART2.mkv
    It is the same event, but 2 separate components;

    First component:
    Code:
    wedding_trish_aaron_2024-03-01_19-38-36_019-PART1.mkv
    wedding_trish_aaron_2024-03-01_19-38-36_019-PART2.mkv
    Second component:
    Code:
    wedding_trish_aaron_2024-03-01_22-07-44_329-PART1.mkv
    wedding_trish_aaron_2024-03-01_22-07-44_329-PART2.mkv
    The issue is that when the 4 files are loaded, they are 2 separate pieces with their own PART1 and 2. So ideally the PART1 of both parts should contain the same timestamp as is currently shown in their filename and then the PART2 should be based on the previous PART1 time. The issue however is all 4 files are considered one after the other and are given timestamps based on a singular component.

    So this...

    Code:
    wedding_trish_aaron_2024-03-01_19-38-36_019-PART1.mkv
    wedding_trish_aaron_2024-03-01_19-38-36_019-PART2.mkv
    wedding_trish_aaron_2024-03-01_22-07-44_329-PART1.mkv
    wedding_trish_aaron_2024-03-01_22-07-44_329-PART2.mkv
    Incorrectly becomes this...

    Code:
    wedding_trish_aaron_2024-03-01_19-38-36_019.mkv
    wedding_trish_aaron_2024-03-01_19-41-30_452.mkv
    wedding_trish_aaron_2024-03-01_19-47-27_885.mkv
    wedding_trish_aaron_2024-03-01_21-09-24_860.mkv
    ...merging the timestamps of all 4 as if they are from a single component.
    Quote Quote  
  18. That's no problem at all, just couple of lines changed in rename_files.py, so I included that file only. So you can download it and use that file instead of that old one.
    Image Attached Files
    Quote Quote  
  19. That's brilliant! Glad to hear it was an easy fix. Thank you so much for all your help with this tool. It has been a real time saver and made the workflow much quicker. I really appreciate you going out of your way and helping me from scratch with this whole thing. Thanks again
    Quote Quote  
  20. no problem,
    for exe compilation I had to do a one line change in rename_files.py, so I include all zip with dependencies.

    Then I used pyinstaller 5.3.x and made one exe file, that could be used on any Windows, without python needed.
    Using this command line, full paths needed, I do not included paths, but I recommend to run it from a directory where all dependencies are:
    Code:
    "pyinstaller.exe"  "rename_files.py" --icon=favicon.ico  --name "Rename Files"  -–onefile -–windowed
    then I got Rename Files.exe, included for download
    Image Attached Files
    Last edited by _Al_; 4th Mar 2024 at 14:19.
    Quote Quote  
  21. exe file in zip:
    Image Attached Files
    Quote Quote  
  22. Originally Posted by _Al_ View Post
    exe file...
    And that is the cherry on top! Nice to have it in 1 single file. Windows Defender kept flagging the download but I presumed it was just some false flags so disabled it to get the download and added the exe to the allow list. Thank you so much for your help!
    Quote Quote  
  23. Everyne can make that executable from those sources, providing python is installed. If for example getting Mac laptop instead of Windows, the same, installing pyinstaller (pip install -U pyinstaller) and then using command line from above, using those sources.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!