less strict about ContentCreateDate format in QuickTime ItemList

Started by dae65, July 24, 2020, 07:13:06 PM

Previous topic - Next topic

dae65

Dear Phil,

Apologies for such a long post. The point is simple: Image::ExifTool is needlessly strict about the MP4 ©day atom. I suggest its format should be just text. Here is why:

The API and the application complain, and do nothing, when we try to write ContentCreateDate in the QuickTime ItemList and UserData groups as a four-digit year:

QuoteWarning: Invalid date/time (use YYYY:mm:dd HH:MM:SS[.ss][+/-HH:MM|Z]) in ItemList:ContentCreateDate (PrintConvInv)

However, they accept, and don't complain about, four-digit years when reading ContentCreateDate from MP4 files:

QuoteContent Create Date             : 1988

I was wondering if you'd be willing to be less strict about what exiftool accepts to write on that tag. As far as I can tell from the documentation references you provide in Image::ExifTool::QuickTime, anything from "1998" to "My son's birthday" should be allowed to go on that tag.



On the one hand, it's true there is a comment in exiftool's source code saying this is how Apple iPhone writes it:

Quote# handle values in the form "2010-02-12T13:27:14-0800" (written by Apple iPhone)

On the other hand, though, I went over thoses references and found nothing saying that the ©day atom has to be like that. Actually, libraries and applications that support MP4 tags assume not much about its format. Here are a few examples:



mp4v2 suggests YYYY-MM-DD but is not strict about it --- "may be incomplete (e.g. just the year)":

Element       Tag   Data Type     Comment                          mp4v2 Name
Release Date  ©day  UTF-8 string  YYYY-MM-DD format, may be        releaseDate
                                  incomplete (e.g. just the year)

and reads and writes it as text (src/itmf/Tags.cpp):

  const string Tags::CODE_RELEASEDATE       = "\xa9" "day";
  [...]
  fetchString(  cim, CODE_RELEASEDATE,       releaseDate,       c.releaseDate );
  [...]
  storeString(  file, CODE_RELEASEDATE,       releaseDate,       c.releaseDate );




AtomicParsley describes it as year:
4char code  Name  Class/Flag  Appearance
©day        Year  1 text      iTunes 4.0

the command-line help message recommends a number or a timestamp:

--year             ,  -y   (num|UTC)    Set the year tag: "moov.udta.meta.ilst.©day.data"

but the code parses it simply as text (main.cpp):

      AtomicInfo *yearData_atom = APar_MetaData_atom_Init(
          "moov.udta.meta.ilst.\251day.data", optarg, AtomFlags_Data_Text);

and the application, accordingly, is happy to write anything on it:
AtomicParsley file.m4a --year 'My birthday' --overWrite



MP4::Info also describes it as year, and extracts it as a 4-byte string:
       
  $tags->{YEAR}     = $tags->{DAY}     if defined ($tags->{DAY});

  [...]
  elsif ($id eq 'DAY')
        {
            $data = substr ($data, 0, 4);
            return 0 if $data==0;
        }
 




mp3tag describes it as year:
Mp3tag  ID3v2.3  ID3v2.4  MP4   Matroska            WMA      iTunes  WMP  Winamp
YEAR    TYER     TDRC     ©day  T=50 DATE_RECORDED  WM/Year  Year    *    Year




Finally, wiki.multimedia.cx refers to ©day as content created year, not date.



If you're willing to do that, I suggest making calls in ValueConvInv, PrintConvInv, etc to:

Image::ExifTool::XMP::FormatXMPDate
Image::ExifTool::XMP::ConvertXMPDate
ConvertDateTime
InverseDateTime

as conditional on whether the value looks like a timestamp to begin with, or at the very least says anything about time:

if ( $val =~ /\b\d{2}:\d{2}:\d{2}\b/ )
{
  ...
}
else
{
  $val;
}




Let me know if I can somehow help with the code. I know the way exiftool deals with timestamps is a big asset to it, as we can see from not a few questions asked about it here. It's just that traditionally ©day is no timestamp.

Thank you! :)

Phil Harvey

I can do this, but it will require using the -n option to avoid the date-time parsing because it would be best if these were written in a standard format.

- 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 ($).

dae65

Quote from: Phil Harvey on July 25, 2020, 06:43:06 AM
I can do this, but it will require using the -n option to avoid the date-time parsing because [...]
Thanks. The -n may well be enough for the command-line tool, but what about the Image::ExifTool API, and applications written by other people using it?

Quote from: Phil Harvey on July 25, 2020, 06:43:06 AM
[...] because it would be best if these were written in a standard format.
Right, it would indeed, but the question is what the standard format is: Apple iTunes writes it as a simple year, whereas the very Apple iPhone writes it as a full UTC, etc.

Other tag editors are highly permissive about it by default.  Writing MP4 tags is a relatively new feature in Image::ExifTool, and I'm really excited about it. Still, in an effort for it to get off on the right foot, don't you agree that it would be better if it be compatible with them by default?

Phil Harvey

Quote from: dae65 on July 25, 2020, 08:25:13 AM
Thanks. The -n may well be enough for the command-line tool, but what about the Image::ExifTool API, and applications written by other people using it?

This is the same as writing the ValueConv value via the API.

Quote
Right, it would indeed, but the question is what the standard format is: Apple iTunes writes it as a simple year, whereas the very Apple iPhone writes it as a full UTC, etc.

Other tag editors are highly permissive about it by default.  Writing MP4 tags is a relatively new feature in Image::ExifTool, and I'm really excited about it. Still, in an effort for it to get off on the right foot, don't you agree that it would be better if it be compatible with them by default?

Makes sense.

- 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 ($).

dae65

Quote from: Phil Harvey on July 27, 2020, 07:16:11 AM
This is the same as writing the ValueConv value via the API.
Good. So the issue has to do with how ©day is printed, not with how it is stored and retrieved, right? I may be wrong, as I'm still trying to finding my way through the API, but doesn't this look as if rules about how a value is to be printed are dictating how it is to be stored? At any rate, users aren't supposed to find out what day, hour, and minute, Beethoven composed a particular symphony; :D an year --- or an year-range at that --- should be acceptable here.

Phil Harvey

Quote from: dae65 on July 27, 2020, 11:02:09 AM
Quote from: Phil Harvey on July 27, 2020, 07:16:11 AM
This is the same as writing the ValueConv value via the API.
Good. So the issue has to do with how ©day is printed, not with how it is stored and retrieved, right?

Not at the moment, but I was proposing that a change that would behave this way.

- 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 ($).

Phil Harvey

ExifTool 12.02 should do what you want when writing a ValueConv value

- 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 ($).