mifi / lossless-cut

The swiss army knife of lossless video/audio editing
https://losslesscut.app/
GNU General Public License v2.0
25.99k stars 1.25k forks source link

Please change the way file times and metadata times are handled #1017

Closed Snelso91 closed 1 month ago

Snelso91 commented 2 years ago

Share information to help me understand No error report was given, and this is not specific to a particular file.

Describe the bug When performing a cut on a video file, lossless cut currently appears to add the amount of time that was cut from the start of the clip to the file "Modified Time" - i.e. if 20 seconds is removed from the start of the video file then lossless cut output file will have a windows file modified time of the initial clip's modified time + 20 seconds. This behaviour implies that the initial modified time of the input video is the starting time of the video, in which case adding the time cut from the video onto the start time would correctly give the new start time, however based on what I have observed and tested I would argue that this is incorrect and the modified time usually denotes the end time of the video.

This is because based on using 2 different modes of shadowplay and OBS to record clips, all 3 methods consistently set the modified time/date of the file to the time that the clip ended at. To be more specific:

  1. For OBS using default settings, an mkv file is produced with a file modified time and file created time equal to the time that the video ended at, but with no metadata times recorded.
  2. For shadowplay instant replay feature (where a clip is recorded after it has happened), an mp4 file is produced with the file modified time, file created time, and all the clip metadata times (such as each of the several "encoded date" and "tagged date" fields/tags for mediainfo, or createdate, modifydate, trackcreatedate, trackmodifydate, mediacreatedate and mediamodifydate tags for exiftool) are equal to the time that the clip ended at.
  3. For shadowplay record feature (where a clip is started and stopped manually like with OBS), an mp4 file is produced with the file modified time, and all the clip metadata times are equal to the time that the clip ended at, however the created time is set to the clip start time.

Therefore, it appears to me that the "standard" way of setting video times is that the time metadata (for files that have it such as mp4) is always set to the video end time, and the file created/modified times are either set to the start of the video or end of the video. Personally, I believe that setting the file created/modified times to the start makes more sense for mp4's since the video end time is already stored in the metadata, and in my opinion viewing start times makes more sense when comparing times, than the end times of a video.

To Reproduce Steps to reproduce the behavior:

  1. Record a screen-capture mp4 video which is recording something like an online clock or windows clock on the screen. This should show that the file/metadata times for this video are the same as what the clock shows at the end of the video.
  2. Open this file in lossless cut.
  3. Remove/cut/trim 20 seconds from the start of the clip in lossless cut and then export.
  4. The lossless cut output file will have new file times of the original end clock time +20 seconds, which is incorrect.

Expected behavior For mp4's, change all of the applicable metadata fields to be equal to the new end datetime of the clip. For example, if 20 seconds is removed/trimmed from the end in lossless cut, then subtract 20 seconds from the original metadata datetime when setting the new metadata.

In addition, set both the file created and modified times to the new/trimmed start datetime of the clip. I.e. take the original end time from the metadata times, then subtract the original length of the clip, then add the amount of time that is cut from the start of the clip in lossless cut. If metadata times cannot be found (such as for OBS mkv files), then assume that the file created/modified time is the end time not the start time, and set the new file created/modified time = the new end time, if time metadata cannot be set on the mkv.

For example, an mp4 video with original metadata end time of 01/01/2022 2:00:00 PM and untrimmed length of 5 minutes with 30 seconds trimmed from the start, would have a new/output file created/modified time of 01/01/2022 2:00:00 PM - 5:00 + 0:30 = 01/01/2022 1:55:30 PM.

Alternatively, if setting the new file created/modified time to the new end time of the clip makes more sense/adheres better to whatever standards there are for video times, then I wouldn't mind that instead of having start times in the file created/modified time. The key thing for me is that lossless cut recognises that the times on the original/input files are end times not start times, and that it at least encodes the new end times into the mp4 metadata, and one of either end or start times into the new created/modified times.

Desktop (please complete the following information):

Additional context I can provide screenshots or metadata text files of my testing with shadowplay/OBS above if required. For now I will leave it with just my description above to avoid wasting space with images that show what I have already described.

mifi commented 2 years ago

Hi.

Therefore, it appears to me that the "standard" way of setting video times is that the time metadata (for files that have it such as mp4) is always set to the video end time, and the file created/modified times are either set to the start of the video or end of the video. Personally, I believe that setting the file created/modified times to the start makes more sense for mp4's since the video end time is already stored in the metadata, and in my opinion viewing start times makes more sense when comparing times, than the end times of a video.

I'm not sure if your observation is the "standard". My observation is a bit different, for example an iPhone recorded video:

Fields that equal to the start of recording:

Fields that equal to the end of recording:

As for handling embedded metadata and making decisions based on it, it's a bit problematic because of many reasons:

I think many people who worked with exiftool already, have realised that there is no 100% correct way of handling dates/times in photos video metadata, and trying to do one thing for all files will surely cause incorrect data to be written. File modification time are always present, and usually always has timezone info (or at least are relative to utc), so it's a more definite source of truth.

So tbh I don't know if it's possible to solve this in a general way.

See also #1027

Snelso91 commented 2 years ago

I'm not sure if your observation is the "standard". My observation is a bit different, for example an iPhone recorded video:

Fields that equal to the start of recording:

  • MediaCreateDate
  • TrackCreateDate
  • CreateDate
  • CreationDate
  • FileModifyDate

Fields that equal to the end of recording:

  • MediaModifyDate
  • TrackModifyDate
  • ModifyDate

As for handling embedded metadata and making decisions based on it, it's a bit problematic because of many reasons:

  • different file formats have different tags with different date formats

    • some store dates only
    • some store date with time
    • some store date with time and milliseconds
    • some store any of the above with timezone
    • some store any of the above without timezone
    • some store any of the above in an ambiguous value that may be UTC or may be local time without any timezone info
    • some files store multiple time and/or date values (which ones to choose?) there are probably 100s of different date/time tags in exiftool
    • some have time/date values for the file itself, and for each track separately
  • ffmpeg only supports some of these values, and doesn't support writing all of them
  • exiftool may support some, but not all

I think many people who worked with exiftool already, have realised that there is no 100% correct way of handling dates/times in photos video metadata, and trying to do one thing for all files will surely cause incorrect data to be written. File modification time are always present, and usually always has timezone info (or at least are relative to utc), so it's a more definite source of truth.

So tbh I don't know if it's possible to solve this in a general way.

See also #1027

Hi,

Thanks for clarifying, I was a little skeptical myself that my test sample size was too small to make a claim about mp4s in general, and certainly for my use case I am pretty much solely working with screen capture videos rather than mobile recordings so I agree it was a little naive to try and generalise based on one use case.

The main reason I brought up this request is because I have already been using exiftool to do some file date correction of previously created, edited (lossless cut) or encoded (handbrake) clips, which is when I noticed the behaviour of lossless cut adding time onto the modification date based on how much was trimmed from the start of the clip. Seeing as this information (the amount trimmed from the start and end of the original clip) cannot be recovered to use for datetime correction in exiftool, etc. after the losslesscut output filename is changed, I wanted to find a way to handle this file datetime and metadata datetime correction inside losslesscut itself, seeing as it already has some logic to change the file modification date based on the amount trimmed from the clip.

I agree that having some option to use an exiftool (as you suggested in #1027) script integrated with lossless cut itself would be ideal, as that provides a general solution for anyone to customise both the metadata times and file times as their use case requires, and would certainly solve the initial problem I was having with datetime correction. Whilst exiftool does have some limitations with the tags it can write, as far as I am aware it is the most comprehensive tool for reading/writing media file metadata and file times, so I would think that it would be the best option for integration with lossless cut to cover the vast majority of use cases, unless you have a better suggestion?

If this isn't possible in the short term, then having some simple dropdown menus or similar in the settings menu to treat the input file modified date as the end time or start time, and to change the output file created to trimmed time start or end and modified to trimmed time start or end, etc. would be the next best solution, as this at least provides a general solution for customising how input and output file times are handled? This would alleviate having to deal with any formatting issues as you have noted can happen with metadata times, as the windows file times are always in the same format, and so won't require exiftool to be read from the input, adjusted based on clip trim times, and then written again to the output. Similarly, I would argue that whilst file modified times are certainly more "truthful"/reliable than metadata times (as we have both observed), whether the modified time refers to the beginning or end of the video varies depending on the video's source, and so having one option to handle this (as is currently implemented in lossless cut) is not going to work correctly for video clips from shadowplay, OBS, and other use cases.

This temporary solution would of course ignore metadata from the input file when making decisions, and would simply pass it through to the output file as lossless cut already does, but that can be corrected by my existing external exiftool scripts by extracting the correct file created and modified times written by lossless cut, whilst waiting for exiftool to be fully integrated into the lossless cut code.

mifi commented 2 years ago

So to summarise, I think this feature request contains of two parts:

Snelso91 commented 2 years ago

So to summarise, I think this feature request contains of two parts:

  • first solution: an option that if enabled will alter the transfer "modified time" behavior:

    • when this setting is enabled, instead of setting output file timestamp to [input file timestamp] + [start cut time] it will instead:
    • set output file timestamp to [input file timestamp] - ([duration] - [end cut time])

For the first solution, I was mainly asking for output modified time to be changed from [input file timestamp] + [start cut time] to input file timestamp] - [end cut time].

I was also saying it would be good to have the option to also possibly choose other permutations of input file format and output file format such as:

  1. Input file modified=start of clip, output file modified=new start of clip (the current solution): [input file timestamp] + [start cut time]
  2. Input file modified=end of clip, output file modified=new end of clip (my preferred option): input file timestamp] - [end cut time]
  3. Input file modified=start of clip, output file modified=new end of clip: [input file timestamp] + [duration] - [end cut time]
  4. Input file modified=end of clip, output file modified=new start of clip: [input file timestamp] - [duration] + [start cut time]

as this would cover all the permutations if other users have similar needs.

In addition, I wanted to be able to choose any of these 4 options for the output file "created time", independently of the file modified time, as this would allow setting stuff such as: Input file modified=end of clip, output file modified=new end of clip: [input file timestamp] - [end cut time], whilst also setting input file modified=end of clip, output file created=new start of clip: [input file timestamp] - [duration] + [start cut time]

  • second solution: in addition to setting output file timestamp, set also exif metadata, based on input metadata (need to define which metadata to use as input and which to use as output, not sure how to do that)

For the second solution, I was asking to set output metadata based on input metadata and other parameters such as [duration], [start cut time] and [end cut time]. This would allow the metadata times to be adjusted based on [start cut time] or [end cut time], similar to the modified time and created time.

Regarding deciding which metadata to use as input/output, I think it would be best for the user to choose because like you said before, there are many possible combinations of tags and formats, so it would be best if left to the user to decide which they want to modify. To answer your question, choosing the input and output tags can be done in tools such as exiftool with commands such as:

exiftool -GlobalTimeShift "hours:minutes:seconds" -TagsFromFile losslesscutinput.mp4 -tag1 -tag2 losslesscutoutput.mp4

where "hours:minutes:seconds" is the time required to shift by such as [start cut time] or -[duration]+[start cut time], etc.

bryc commented 2 years ago

I'm also affected by this issue and only now realizing it's been adding time to the end time. Not a huge deal in some cases as trail cams have their own timestamp, and most files contain a start-date in the filename itself.

The ideal solution, would be to leave date-modified as is. Just copy it 1:1. Because the file-modified date almost always represents the time it finished saving/downloading. It would make more sense to add the time offset to the file-created field instead. But considering that field is relatively volatile, it's kind of pointless, because it can reset easily just by moving/copying between drives.

Of course, if the date-modified means "end time", then it shouldn't change if you only crop out the first 10 minutes or so. End time doesn't change, but start time does.

I'd prefer if the option to disable offset-adding were available, IMO it's more of a safe default for most users, as its not really changing what might not need to be changed.

danelynnn commented 1 year ago

I have to say that this is a problem I'm having too! the timestamps are severely messed up especially on my end as most of the files I work with are several hours long, so I'm really hoping this does get added as a new feature.

mifi commented 1 year ago

@danelynnn care to elaborate on «severely messed up»?

bryc commented 1 year ago

Recently I found myself needing to manually change the date-modified field in files created with lossless-cut. A lot of my footage contains a timestamp in the filename itself (the start time). The date modified is usually (the end time). So rather than keep an altered end-time that is no longer accurate, I subtracted time to make it match the start time.

It would be very good if there was an option to leave the date-modified field unchanged.

mifi commented 1 year ago

Have now implemented customisation of the modified date behaviour according to https://github.com/mifi/lossless-cut/issues/1017#issuecomment-1049097115

Unfortunately Node.js doesn't support setting "file created time" aka birthtime. A possibility is to use https://github.com/baileyherbert/utimes however I'm a bit hesitant with adding native complied deps.

mifi commented 1 month ago

because customisable timstamp transfer is already implemented, i'm closing this for now. can reopen or create a new issue if there are things that are still needed