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 (https://github.com/sergiomb2/libmp4v2) 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 (https://github.com/sergiomb2/libmp4v2/blob/master/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 (http://atomicparsley.sourceforge.net/mpeg-4files.html) 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 (https://github.com/wez/atomicparsley/blob/master/src/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 (https://metacpan.org/release/MP4-Info/source/Info.pm) 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 (https://help.mp3tag.de/main_tags.html) 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 (https://wiki.multimedia.cx/index.php/QuickTime_container) 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! :)
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?
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
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.
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