Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use date from GPS or exif #114

Open
wants to merge 19 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions pkg/dji/dji.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ import (
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"

"github.com/dustin/go-humanize"
"github.com/fatih/color"
"github.com/karrick/godirwalk"
"github.com/konradit/mmt/pkg/media"
"github.com/konradit/mmt/pkg/utils"
"github.com/minio/minio/pkg/disk"
"github.com/rwcarlsen/goexif/exif"
"github.com/vbauerster/mpb/v8"
"gopkg.in/djherbis/times.v1"
)

func getDeviceNameFromPhoto(path string) (string, error) { //nolint:unused
Expand Down Expand Up @@ -97,19 +96,11 @@ func (Entrypoint) Import(params utils.ImportParams) (*utils.Result, error) {
if !ftype.Regex.MatchString(de.Name()) {
continue
}
t, err := times.Stat(osPathname)
if err != nil {
return godirwalk.SkipThis
}
d := t.ModTime()

mediaDate := d.Format("02-01-2006")
if strings.Contains(params.DateFormat, "yyyy") && strings.Contains(params.DateFormat, "mm") && strings.Contains(params.DateFormat, "dd") {
mediaDate = d.Format(utils.DateFormatReplacer.Replace(params.DateFormat))
}
d := media.GetFileTime(osPathname, false, false)
mediaDate := media.GetMediaDate(d, params.DateFormat)

// check if is in date range

if d.Before(params.DateRange[0]) || d.After(params.DateRange[1]) {
return godirwalk.SkipThis
}
Expand Down
33 changes: 5 additions & 28 deletions pkg/gopro/gopro.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ import (
"github.com/fatih/color"
"github.com/karrick/godirwalk"
mErrors "github.com/konradit/mmt/pkg/errors"
"github.com/konradit/mmt/pkg/media"
"github.com/konradit/mmt/pkg/utils"
"github.com/maja42/goval"
"github.com/minio/minio/pkg/disk"
"github.com/vbauerster/mpb/v8"
"gopkg.in/djherbis/times.v1"
)

/*
Expand Down Expand Up @@ -159,8 +159,8 @@ folderLoop:
continue fileTypeLoop
}

d := getFileTime(osPathname, true)
mediaDate := getMediaDate(getFileTime(osPathname, true), params.DateFormat)
d := media.GetFileTime(osPathname, true, true)
mediaDate := media.GetMediaDate(media.GetFileTime(osPathname, true, true), params.DateFormat)

if d.Before(params.DateRange[0]) || d.After(params.DateRange[1]) {
return godirwalk.SkipThis
Expand Down Expand Up @@ -336,8 +336,8 @@ func importFromGoProV1(params utils.ImportParams) utils.Result {
continue
}

d := getFileTime(osPathname, true)
mediaDate := getMediaDate(d, params.DateFormat)
d := media.GetFileTime(osPathname, true, true)
mediaDate := media.GetMediaDate(d, params.DateFormat)

if d.Before(params.DateRange[0]) || d.After(params.DateRange[1]) {
return godirwalk.SkipThis
Expand Down Expand Up @@ -550,29 +550,6 @@ func readInfo(inBytes []byte) (*Info, error) {
return &gpVersion, nil
}

func getFileTime(osPathname string, utcFix bool) time.Time {
var d time.Time
t, err := times.Stat(osPathname)
if err != nil {
log.Fatal(err.Error())
}
d = t.ModTime()
if utcFix {
zoneName, _ := d.Zone()
newTime := strings.Replace(d.Format(time.UnixDate), zoneName, "UTC", -1)
d, _ = time.Parse(time.UnixDate, newTime)
}
return d
}

func getMediaDate(d time.Time, dateFormat string) string {
mediaDate := d.Format("02-01-2006")
if strings.Contains(dateFormat, "yyyy") && strings.Contains(dateFormat, "mm") && strings.Contains(dateFormat, "dd") {
mediaDate = d.Format(utils.DateFormatReplacer.Replace(dateFormat))
}
return mediaDate
}

func parse(folder string, name string, osPathname string, bufferSize int, bar *mpb.Bar, modTime time.Time) error {
if _, err := os.Stat(folder); os.IsNotExist(err) {
mkdirerr := os.MkdirAll(folder, 0o755)
Expand Down
16 changes: 3 additions & 13 deletions pkg/insta360/insta360.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ import (
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"

"github.com/dustin/go-humanize"
"github.com/fatih/color"
"github.com/karrick/godirwalk"
"github.com/konradit/mmt/pkg/media"
"github.com/konradit/mmt/pkg/utils"
"github.com/minio/minio/pkg/disk"
"github.com/vbauerster/mpb/v8"
"gopkg.in/djherbis/times.v1"
)

func getDeviceName(manifest string) string {
Expand Down Expand Up @@ -91,20 +90,11 @@ func (Entrypoint) Import(params utils.ImportParams) (*utils.Result, error) {
if !ftype.Regex.MatchString(de.Name()) {
continue
}
t, err := times.Stat(osPathname)
if err != nil {
return godirwalk.SkipThis
}

d := t.ModTime()

mediaDate := d.Format("02-01-2006")
if strings.Contains(params.DateFormat, "yyyy") && strings.Contains(params.DateFormat, "mm") && strings.Contains(params.DateFormat, "dd") {
mediaDate = d.Format(utils.DateFormatReplacer.Replace(params.DateFormat))
}
d := media.GetFileTime(osPathname, false, false)
mediaDate := media.GetMediaDate(d, params.DateFormat)

// check if is in date range

if d.Before(params.DateRange[0]) || d.After(params.DateRange[1]) {
return godirwalk.SkipThis
}
Expand Down
181 changes: 181 additions & 0 deletions pkg/media/dates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package media

import (
"bytes"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"time"

"github.com/konradit/gopro-utils/telemetry"
"github.com/konradit/mmt/pkg/utils"
"github.com/konradit/mmt/pkg/videomanipulation"
"github.com/rwcarlsen/goexif/exif"
"gopkg.in/djherbis/times.v1"
)

func getGPSTime(x *exif.Exif, date *time.Time) bool {
var gpsDateTime string

gpsDateStamp, err := x.Get(exif.GPSDateStamp)
if err != nil {
return false
}
gpsTimeStamp, err := x.Get(exif.GPSTimeStamp)
if err != nil {
return false
}

gpsD, err := gpsDateStamp.StringVal()
if err != nil {
return false
}

// convert rational to string
gpsH, _, err := gpsTimeStamp.Rat2(0)
if err != nil {
return false
}
gpsM, _, err := gpsTimeStamp.Rat2(1)
if err != nil {
return false
}
gpsS, _, err := gpsTimeStamp.Rat2(2)
if err != nil {
return false
}

gpsDateTime = fmt.Sprintf("%s %02d:%02d:%02d", gpsD, gpsH, gpsM, gpsS)

// parse the string into time
d, err := time.Parse("2006:01:02 15:04:05", gpsDateTime)
if err == nil {
*date = d
return true
}

return false
}

func getFileTimeExif(osPathname string, goPro bool) time.Time {
var date time.Time

if strings.Contains(osPathname, ".WAV") {
osPathname = osPathname[:len(osPathname)-len(filepath.Ext(osPathname))] + ".MP4"
}

t, err := times.Stat(osPathname)
if err != nil {
log.Fatal(err.Error())
}

d := t.ModTime()

// First search in gps track
if goPro && strings.Contains(osPathname, ".MP4") {
if getTimeFromMP4(osPathname, &date) {
return date
}
}

f, err := os.Open(osPathname)
if err != nil {
return d
}
defer f.Close()
x, err := exif.Decode(f)
if err != nil {
return d
}

if getGPSTime(x, &date) {
return date
}

// define the list of possible tags to extract date from
dateTags := []string{"DateTimeOriginal", "DateTime", "DateTimeDigitized"}

// loop for each tag and return the first valid date
for _, tag := range dateTags {
// get value of tag from exif
tt, err := x.Get(exif.FieldName(tag))
if err != nil {
tts, _ := tt.StringVal()
date, err = time.Parse("2006:01:02 15:04:05", tts)
if err != nil {
continue
}
return date
}
}

return d
}

func getTimeFromMP4(videoPath string, date *time.Time) bool {
vman := videomanipulation.New()
data, err := vman.ExtractGPMF(videoPath)
if err != nil {
return false
}

reader := bytes.NewReader(*data)

lastEvent := &telemetry.TELEM{}

for {
event, err := telemetry.Read(reader)
if err != nil && err != io.EOF {
return false
} else if err == io.EOF || event == nil {
break
}

if lastEvent.IsZero() {
*lastEvent = *event
event.Clear()
continue
}

err = lastEvent.FillTimes(event.Time.Time)
if err != nil {
return false
}

telems := lastEvent.ShitJson()
for _, telem := range telems {
if telem.Latitude != 0 && telem.Longitude != 0 {
*date = time.UnixMicro(telem.TS)

return true
}
}
*lastEvent = *event
}

return false
}

func GetFileTime(osPathname string, utcFix bool, goPro bool) time.Time {
t := getFileTimeExif(osPathname, goPro)

if utcFix {
zoneName, _ := t.Zone()
newTime := strings.Replace(t.Format(time.UnixDate), zoneName, "UTC", -1)
t, _ = time.Parse(time.UnixDate, newTime)
}

return t
}

func GetMediaDate(d time.Time, dateFormat string) string {
mediaDate := d.Format("02-01-2006")
if strings.Contains(dateFormat, "yyyy") && strings.Contains(dateFormat, "mm") && strings.Contains(dateFormat, "dd") {
mediaDate = d.Format(utils.DateFormatReplacer.Replace(dateFormat))
}

return mediaDate
}