The problem#
My Android phone's camera app has an option to take a
"motion photo", which, similar to the iOS
"live photo" feature, records a short, silent video along
with the photo. When viewing the photos on the phone, there's an option
to play the video. But image viewer programs on my computer like
Eye of GNOME (eog
) do not support playing them.
The solution#
ExifTool (in Debian, the package name is
libimage-exiftool-perl
) can extract the video to a file
using this example from a forum post:
exiftool -b -EmbeddedVideoFile photo.jpg > photo_motion.mp4
You can also play it directly without saving it to a file by piping to VLC:
exiftool -b -EmbeddedVideoFile photo.jpg | vlc -
The details#
Exif#
Exif is the standard for storing metadata along with photos. Its commonly used for things like identifying the camera settings, when the photo was taken, and where the photo was taken1.
In this case, it's also be used to store the video recorded along with the photo, as strange as it may sound to refer to a video larger than the photo as "metadata" of the photo.
Many image viewers have some way of viewing the Exif data. In
Eye of GNOME, selecting "Properties" from the menu shows the most common
metadata along with a "Show Details" button to show the exact values of
all of the data. Looking there on a photo with a motion photo, I see an
"XMP Other" section with a "GCamera:MotionPhoto" tag and some related
tags indicating there's an item with a video/mp4
MIME type.
Extracting with ExifTool#
I happened upon this forum post explaining that the
-b -EmbeddedVideoFile
options would extract the motion photo.
The -EmbeddedVideoFile
flag tells it to output the tag named
"EmbeddedVideoFile", but if you give just that option it says
Embedded Video File : (Binary data 3994570 bytes, use -b option to extract)
Since it does not contain text, you have to provide the -b
option to
tell it you actually want it to output binary data.
Note that for files that do not have an "EmbeddedVideoFile", both commands will output nothing at all, which can be used to check whether an image has a motion photo.
Playing the video#
The original example I found output the video to a file, but I thought
it should be possible to avoid that step. I tried mplayer
for this
first as it's usually more flexible than VLC, but to my surprise piping
to mplayer -
failed with multiple copies of the following error:
Cannot seek backward in linear streams!
Seek failed
even though piping to vlc -
as I suggest above works just fine.
This post suggests a workaround: mplayer - -cache 8092
does work by telling mplayer
to keep around some cache to be able
to seek backwards within. I originally tried a smaller cache size of
2048 which did not work, so you may need to adjust the value.
Extracting without ExifTool#
I also came across this script, which does not use
ExifTool, instead using grep
to find the offset of a binary
string in the file. I did not try it myself, but it also is referencing
different motion photo formats, so perhaps it may be necessary to read
motion photos generated by different or older Android phones.
User-friendly viewer#
PhotoQt claims "Support for Motion Photos and Apple Live Photos", so if you can get it to run, it should also solve this problem.
But I had trouble getting it to actually run. As this Debian bug points out, it needs more dependencies to run than the package specifies. But even once I figured out what dependencies it needed to run, it segfaulted when actually viewing a motion photo.
I ran it under gdb
to see if I could get more information:
$ gdb photoqt
GNU gdb (Debian 15.2-1) 15.2
[...]
(No debugging symbols found in photoqt)
(gdb) start 'photo.jpg'
Temporary breakpoint 1 at 0x920e0
Starting program: /usr/bin/photoqt 'photo.jpg'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, 0x00005555555e60e0 in main ()
(gdb) c
(The parts I actually typed at the (gdb)
prompt were start 'photo.jpg'
to actually run it and give it the command-line arguments and c
to
continue from the breakpoint it automatically set at the start of
the program.)
After minimal interaction, it crashed and I typed bt
to get a
backtrace:
Thread 1 "photoqt" received signal SIGSEGV, Segmentation fault.
0x00007fffedd3a074 in XDisplayString () from /lib/x86_64-linux-gnu/libX11.so.6
(gdb) bt
#0 0x00007fffedd3a074 in XDisplayString ()
at /lib/x86_64-linux-gnu/libX11.so.6
#1 0x00007fff96c05ee5 in __vaDriverInit_1_0 ()
at /usr/lib/x86_64-linux-gnu/dri/nvidia_drv_video.so
#2 0x00007fffedc5536b in vaInitialize () at /lib/x86_64-linux-gnu/libva.so.2
#3 0x00007fffee64ca98 in ??? () at /lib/x86_64-linux-gnu/libavutil.so.59
#4 0x00007fffee63e82c in av_hwdevice_ctx_create ()
at /lib/x86_64-linux-gnu/libavutil.so.59
#5 0x00007fffbc59dc9b in ??? ()
at /usr/lib/x86_64-linux-gnu/qt6/plugins/multimedia/libffmpegmediaplugin.so
#6 0x00007fffbc5a104c in ??? ()
[...]
Once I saw the segfault's backtrace included references to
libffmpegmediaplugin.so
, I figured the problem was unlikely to be
solved by installing more dependencies, so I decided to find some other
way to view the motion photos, eventually finding the forum post I
linked above.
Comments
Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.
There are no comments yet.