Metadata: Support time zones in ExifTool JSON files #727

This commit is contained in:
Michael Mayer 2020-12-22 01:52:36 +01:00
parent a16a5ee16a
commit bc535b6248
4 changed files with 133 additions and 2 deletions

View file

@ -13,8 +13,8 @@ import (
type Data struct {
DocumentID string `meta:"ImageUniqueID,OriginalDocumentID,DocumentID"`
InstanceID string `meta:"InstanceID,DocumentID"`
TakenAt time.Time `meta:"DateTimeOriginal,CreateDate,MediaCreateDate,DateTimeDigitized,DateTime"`
TakenAtLocal time.Time `meta:"DateTimeOriginal,CreateDate,MediaCreateDate,DateTimeDigitized,DateTime"`
TakenAt time.Time `meta:"DateTimeOriginal,CreateDate,MediaCreateDate,ContentCreateDate,DateTimeDigitized,DateTime"`
TakenAtLocal time.Time `meta:"DateTimeOriginal,CreateDate,MediaCreateDate,ContentCreateDate,DateTimeDigitized,DateTime"`
TimeZone string `meta:"-"`
Duration time.Duration `meta:"Duration,MediaDuration,TrackDuration"`
Codec string `meta:"CompressorID,Compression,FileType"`

View file

@ -76,6 +76,8 @@ func (data *Data) Exiftool(jsonData []byte, originalName string) (err error) {
if tv, err := time.Parse("2006:01:02 15:04:05", s); err == nil {
fieldValue.Set(reflect.ValueOf(tv.Round(time.Second).UTC()))
} else if tv, err := time.Parse("2006:01:02 15:04:05-07:00", s); err == nil {
fieldValue.Set(reflect.ValueOf(tv.Round(time.Second)))
}
case time.Duration:
fieldValue.Set(reflect.ValueOf(StringToDuration(jsonValue.String())))
@ -120,6 +122,10 @@ func (data *Data) Exiftool(jsonData []byte, originalName string) (err error) {
if loc, err := time.LoadLocation(data.TimeZone); err != nil {
log.Warnf("metadata: unknown time zone %s (exiftool)", data.TimeZone)
} else if tl, err := time.ParseInLocation("2006:01:02 15:04:05", data.TakenAtLocal.Format("2006:01:02 15:04:05"), loc); err == nil {
if localUtc, err := time.ParseInLocation("2006:01:02 15:04:05", data.TakenAtLocal.Format("2006:01:02 15:04:05"), time.UTC); err == nil {
data.TakenAtLocal = localUtc
}
data.TakenAt = tl.Round(time.Second).UTC()
} else {
log.Errorf("metadata: %s (exiftool)", err.Error()) // this should never happen

View file

@ -551,4 +551,28 @@ func TestJSON(t *testing.T) {
assert.Equal(t, 0, data.FocalLength)
assert.Equal(t, 1, int(data.Orientation))
})
t.Run("date.mov.json", func(t *testing.T) {
data, err := JSON("testdata/date.mov.json", "")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, CodecAvc1, data.Codec)
assert.Equal(t, "6s", data.Duration.String())
assert.Equal(t, "2015-06-10 14:06:09 +0000 UTC", data.TakenAtLocal.String())
assert.Equal(t, "2015-06-10 11:06:09 +0000 UTC", data.TakenAt.String())
assert.Equal(t, "Europe/Moscow", data.TimeZone)
assert.Equal(t, 1920, data.Width)
assert.Equal(t, 1080, data.Height)
assert.Equal(t, 1080, data.ActualWidth())
assert.Equal(t, 1920, data.ActualHeight())
assert.Equal(t, 6, data.Orientation)
assert.Equal(t, float32(55.5636), data.Lat)
assert.Equal(t, float32(37.9824), data.Lng)
assert.Equal(t, "Apple", data.CameraMake)
assert.Equal(t, "iPhone 6 Plus", data.CameraModel)
assert.Equal(t, "", data.LensModel)
})
}

101
internal/meta/testdata/date.mov.json vendored Normal file
View file

@ -0,0 +1,101 @@
[{
"SourceFile": "/photoprism/originals/2020/12/20201222_000924_663B50DC.mov",
"ExifToolVersion": 11.88,
"FileName": "20201222_000924_663B50DC.mov",
"Directory": "/photoprism/originals/2020/12",
"FileSize": "14 MB",
"FileModifyDate": "2020:12:22 00:09:30+00:00",
"FileAccessDate": "2020:12:22 00:09:30+00:00",
"FileInodeChangeDate": "2020:12:22 00:09:30+00:00",
"FilePermissions": "rwxr-xr-x",
"FileType": "MOV",
"FileTypeExtension": "mov",
"MIMEType": "video/quicktime",
"MajorBrand": "Apple QuickTime (.MOV/QT)",
"MinorVersion": "0.0.0",
"CompatibleBrands": ["qt "],
"MediaDataSize": 14675292,
"MediaDataOffset": 36,
"MovieHeaderVersion": 0,
"TimeScale": 600,
"Duration": "6.83 s",
"PreferredRate": 1,
"PreferredVolume": "100.00%",
"PreviewTime": "0 s",
"PreviewDuration": "0 s",
"PosterTime": "0 s",
"SelectionTime": "0 s",
"SelectionDuration": "0 s",
"CurrentTime": "0 s",
"NextTrackID": 3,
"TrackHeaderVersion": 0,
"TrackCreateDate": "2015:06:10 11:06:09",
"TrackModifyDate": "2015:06:10 11:06:16",
"TrackID": 1,
"TrackDuration": "6.83 s",
"TrackLayer": 0,
"TrackVolume": "0.00%",
"ImageWidth": 1920,
"ImageHeight": 1080,
"CleanApertureDimensions": "1920x1080",
"ProductionApertureDimensions": "1920x1080",
"EncodedPixelsDimensions": "1920x1080",
"GraphicsMode": "ditherCopy",
"OpColor": "32768 32768 32768",
"CompressorID": "avc1",
"SourceImageWidth": 1920,
"SourceImageHeight": 1080,
"XResolution": 72,
"YResolution": 72,
"CompressorName": "H.264",
"BitDepth": 24,
"VideoFrameRate": 30.007,
"MatrixStructure": "1 0 0 0 1 0 0 0 1",
"MediaHeaderVersion": 0,
"MediaCreateDate": "2015:06:10 11:06:09",
"MediaModifyDate": "2015:06:10 11:06:16",
"MediaTimeScale": 44100,
"MediaDuration": "6.90 s",
"MediaLanguageCode": "und",
"Balance": 0,
"HandlerClass": "Data Handler",
"HandlerVendorID": "Apple",
"HandlerDescription": "Core Media Data Handler",
"AudioFormat": "mp4a",
"AudioBitsPerSample": 16,
"AudioSampleRate": 44100,
"LayoutFlags": "Mono",
"AudioChannels": 1,
"PurchaseFileFormat": "mp4a",
"SoftwareVersion-rus": 8.3,
"ContentCreateDate-rus": "2015:06:10 14:06:09+03:00",
"GPSCoordinates-rus": "55 deg 33' 48.96\" N, 37 deg 58' 56.64\" E, 141.315 m Above Sea Level",
"Model-rus": "iPhone 6 Plus",
"Make-rus": "Apple",
"XMPToolkit": "Image::ExifTool 11.16",
"DateTimeOriginal": "2015:06:10 14:06:09+03:00",
"CreateDate": "2015:06:10 14:06:09+03:00",
"ModifyDate": "2015:06:10 14:06:09+03:00",
"HandlerType": "Metadata Tags",
"CreationDate-rus-RU": "2015:06:10 14:06:09+03:00",
"Model-rus-RU": "iPhone 6 Plus",
"Software-rus-RU": 8.3,
"GPSCoordinates-rus-RU": "55 deg 33' 48.96\" N, 37 deg 58' 56.64\" E, 141.315 m Above Sea Level",
"Make-rus-RU": "Apple",
"SoftwareVersion": 8.3,
"ContentCreateDate": "2015:06:10 14:06:09+03:00",
"GPSCoordinates": "55 deg 33' 48.96\" N, 37 deg 58' 56.64\" E, 141.315 m Above Sea Level",
"Model": "iPhone 6 Plus",
"Make": "Apple",
"CreationDate": "2015:06:10 14:06:09+03:00",
"Software": 8.3,
"ImageSize": "1920x1080",
"Megapixels": 2.1,
"AvgBitrate": "17.2 Mbps",
"GPSAltitude": "141.315 m",
"GPSAltitudeRef": "Above Sea Level",
"GPSLatitude": "55 deg 33' 48.96\" N",
"GPSLongitude": "37 deg 58' 56.64\" E",
"Rotation": 90,
"GPSPosition": "55 deg 33' 48.96\" N, 37 deg 58' 56.64\" E"
}]