ivandokov / phockup

Media sorting tool to organize photos and videos from your camera in folders by year, month and day.
MIT License
856 stars 108 forks source link

Add support for live photos #208

Open qlyoung opened 1 year ago

qlyoung commented 1 year ago

Look for MediaGroupUUID and ContentIdentifier EXIF tags. These are present in media files which are part of live photo pairs. If found, any future files with the same UUID are named the same as the first one and placed in the same directory.

With this change, live photos and their associated .mov files are moved together.

ivandokov commented 1 year ago

Hello @qlyoung. That's wonderful addition to the software. Please add unit tests to the PR and I will happily merge it.

qlyoung commented 1 year ago

Sweet! I figured i'd make sure it was wanted before bothering with tests. Will do

On Wed, Aug 30, 2023, at 3:46 AM, Ivan Dokov wrote:

Hello @qlyoung https://github.com/qlyoung. That's wonderful addition to the software. Please add unit tests to the PR and I will happily merge it.

— Reply to this email directly, view it on GitHub https://github.com/ivandokov/phockup/pull/208#issuecomment-1698663698, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABUCX66K4C5N633H2XCVWX3XX3VU5ANCNFSM6AAAAAA4D5B2HE. You are receiving this because you were mentioned.Message ID: @.***>

rob-miller commented 1 year ago

@qlyoung Any progress on this? It is a feature I would like to have.

Just a sidenote from spending the morning writing phockup test code: if you are using vscode for development, the pytest fixture is not compatible with addopts = --disable-socket in pytest.ini. That slowed me down for a while.

qlyoung commented 1 year ago

No progress on writing tests. I haven't found time to sit down and learn this project's testing setup.

I went ahead and pushed the latest version of this change though, so if you care to build it yourself, the code is in the branch referenced by this PR

rob-miller commented 1 year ago

I think this is what's needed:

  def test_process_livephoto(mocker):
      shutil.rmtree('output', ignore_errors=True)
      mocker.patch.object(Phockup, 'check_directories')
      mocker.patch.object(Phockup, 'walk_directory')
      mocker.patch.object(Exif, 'data')
      Exif.data.return_value = {
          "MIMEType": "image/heic",
          "MediaGroupUUID": "492774F4-34F4-4A0E-97E4-69F46D335610"
      }
      phockup = Phockup('input', 'output', move=True)
      open("input/tmp_20170102_010101.HEIC", "w").close()
      open("input/tmp_20170103_010101.MOV", "w").close()
      phockup.process_file("input/tmp_20170102_010101.HEIC")
      Exif.data.return_value = {
          "MIMEType": "video/quicktime",
          "ContentIdentifier": "492774F4-34F4-4A0E-97E4-69F46D335610"
      }
      phockup.process_file("input/tmp_20170103_010101.MOV")
      assert os.path.isfile("output/2017/01/02/20170102-010101.heic")
      assert os.path.isfile("output/2017/01/02/20170102-010101.mov")
      shutil.rmtree('output', ignore_errors=True)

Note that the test highlights that the second file gets renamed to match the first, but I think this is as desired. Also, I suspect the processing may fail with concurrency enabled.