Lossless cut file name time suffix adding to createdate

Started by peho, March 19, 2020, 05:55:13 AM

Previous topic - Next topic

peho

I've started to use 'lossless cut' to crop video files (most Gopro).
It gives me a file suffix with crop times.
How can I give the cropped mp4 file a new createDate and fileName that is based on the start time (old createDate+startTime) in file name?
It would be great if:
- I could give a folder/directory as an attribute to the command with both jpg's and mp4's.
- Probably not one command, but I would prefer it if I could drop the folder from my windows file browser to a bat file.
- if the command could handle start time zero. Then the new fileName needs a number suffix to be unique.
- All possible meta data to be copied from original file without suffix to new file(s) with suffix. I lose a lot of meta data when using lossless cut, among that gps. (I know of the limitation of copying proprietary QuickTime fields)

Example files in dir:
2019-01-07 18-22-31.MP4
2019-01-07 18-35-56-00.00.05.004-00.00.10.009.MP4
2019-01-07 18-35-56.MP4
2019-01-07 18-36-22-00.00.00.000-00.00.05.004.MP4
2019-01-07 18-36-22.MP4
2019-01-07 18-44-07-00.00.04.004-00.00.09.009.MP4
2019-01-07 18-44-07.MP4
2019-01-07 18-45-36-00.00.01.001-00.00.08.008.MP4
2019-01-07 18-45-36-00.00.14.014-00.00.19.019.MP4
2019-01-07 18-45-36.MP4
2019-01-07 19-11-33-00.00.00.000-00.00.08.008.MP4
2019-01-07 19-11-33.MP4
2019-01-07 19-12-06.JPG
2019-01-07 19-12-16.JPG
2019-01-07 19-12-25.JPG
2019-01-07 19-12-28.JPG
2019-01-07 19-16-08.MP4
2019-01-07 19-16-35.JPG
2019-01-07 19-16-38.JPG


My bat file today:
exiftool -ext dng -ext gpr "-CreateDate<DateTimeOriginal" %1 -overwrite_original -charset filename= -m -progress:
exiftool -IF "not $CreateDate" "-CreateDate<FileName" %1 -overwrite_original -charset filename= -api quicktimeutc -m -progress:
exiftool "-FileName<CreateDate" -d "%%Y-%%m-%%d %%H-%%M-%%S%%%%-c.%%%%e" %1 -api largefilesupport=1 -overwrite_original -charset filename= -m -progress: -k

Phil Harvey

This command in a .bat file may do what you want:

exiftool "-filename<${filename;s/-(\d{2}\.\d{2}\.\d{2}).*//;my $s=$1;tr/-/:/;$s=~tr/./:/;ShiftTime($s);tr/:/-/}%%-c.%%e" -tagsfromfile "%%d%%19f.%%e" -all:all -if "$filename =~ /\d{2}\.\d{2}\.\d{2}/" -ext mp4 %*

The expression is made more complex because ShiftTime isn't very flexible about the separators it expects, so I've had to translate them all to colons beforehand and back afterward.

You should test this command thoroughly to make sure it is doing what you want before running it on your files.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

peho

This looks really cool. Thanks.
I never thought that it could be possible to combine the renaming and the metadata copy.
I really need to dig deeper into regex, but I got a lot of info here to work on.
Now test phase.

peho

Tested back and forth and it's working great.
I've duplicated the calculation to both change date tags and rename file.
Is it possible to do the calculation once and pass that to two tags?

"exiftool -allDates<${filename;s/-(\d{2}\.\d{2}\.\d{2}).*//;my $s=$1;tr/-/:/;$s=~tr/./:/;ShiftTime($s);tr/:/-/}"
"-fileName<${filename;s/-(\d{2}\.\d{2}\.\d{2}).*//;my $s=$1;tr/-/:/;$s=~tr/./:/;ShiftTime($s);tr/:/-/}%%-c.%%e"

Phil Harvey

Quote from: peho on March 19, 2020, 09:14:33 AM
Is it possible to do the calculation once and pass that to two tags?

Yes, by creating a user-defined Composite tag to do this for you.  Here is the config file that will do it:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        MyTime => {
            Require => 'FileName',
            ValueConv => q{
                return undef unless $val =~ s/-(\d{2}\.\d{2}\.\d{2}).*//;
                my $s = $1;
                $val =~ tr/-/:/;
                $s =~ tr/./:/;
                ShiftTime($val, $s);
                $val =~ tr/:/-/;
                return $val;
            },
        },
    },
);
1;  #end


then the command becomes:

exiftool -config mytime.config "-allDates<mytime" "-fileName<$mytime%%-c.%%e"

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).


peho

Using your above examples and they are working perfectly.

When copying tags from the original mp4 file, you used 'tagsfromfile "%%d%%19f.%%e" -all:all' in your example.

In this case, when the file name consists of just date and time, I know the length of the original mp4 file.
I've other examples where I have video type or model in name and, then the above can't be used.
For instance:
2019-01-23 10-52-08 1920x1080_29.97fps_avc1.MP4 (original/source file)
2019-01-23 10-52-08 1920x1080_29.97fps_avc1-00.00.00.000-00.00.13.012.MP4 (target/destination file)
2019-01-23 10-52-08 1920x1080_29.97fps_avc1-00.00.19.886.jpeg (target/destination file)

Is it possible to copy tags from the original file above without knowing the length, just that all file name in original (without ext) is included in target file?

If it's not, is it possible if you know the format, and can derive a name with the help of a regex on the target file name? Or maybe with a function on a regex calculate the length of source file and put it into %%19f?

Phil Harvey

You can't use a regex as an argument to -tagsfromfile.  In this case, one could possibly use the HardLink feature to create a set of links with the proper file names.  I'll have to come back to this when I have more time to give you a specific example of how to do this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

peho

Thanks for thinking it through and pointing in the direction of how to solve this. I'll come back if I'm going to dig into this further and then throwing my head in the wall...

Phil Harvey

OK, something like this maybe (in a .bat file):

exiftool -config mytime.config "-hardlink<links/${filename;s/-(\d{2}\.\d{2}\.\d{2}).*//}-%%.4c.%%e" -if "$mytime" -ext mp4 %*
exiftool -tagsfromfile "%1/%%-.5f.%%e" -all:all "-alldates<mytime" links
exiftool -config mytime.config "-allDates<mytime" "-fileName<$mytime%%-c.%%e -if "$mytime" -ext mp4 %*"
<then a command to delete the links directory>


The first command creates a set of link files pointing to the cut files but with a fixed-length (5-character) suffix.

The second command copies all tags from the original files to the cut files via the hard links.

The third command renames the files and updates the 3 command date/time tags from the start time of the cut file.

I haven't tested this, but it has a chance of doing what you want.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).