Le Google Pixel 2 et probablement d'autres téléphones ont depuis la capacité de couvrir "Motion Photos". Celles-ci sont enregistrées en tant que MVIMG et relativement grandes.
Je cherche un moyen de supprimer/extraire la vidéo.
Jusqu'à présent, j'ai trouvé une balise exif prometteuse
$ exiftool -xmp:all MVIMG_123.jpg
XMP Toolkit : Adobe XMP Core 5.1.0-jc003
Micro Video : 1
Micro Video Version : 1
Micro Video Offset : 4032524
Je pensais que la vidéo pouvait être présente avec le décalage spécifié, mais cela ne fonctionne pas:
$ dd if=MVIMG_123.jpg of=video.mp4 bs=4032524 skip=1
$ file video.mp4
video.mp4: data
Existe-t-il des ressources qui documentent l'intégration? Existe-t-il même des outils pour supprimer/extraire la vidéo?
J'ai trouvé https://github.com/cliveontoast/GoMoPho qui recherche l'en-tête mp4 puis vide la vidéo.
Nous pouvons faire de même, en recherchant ftypmp4
à partir de l'en-tête MP4 (le fichier réel commence 4 octets plus tôt):
Ainsi pour extraire des vidéos:
for i in MVIMG*.jpg; do \
ofs=$(grep -F --byte-offset --only-matching --text ftypmp4 "$i"); \
ofs=${ofs%:*}; \
[[ $ofs ]] && dd "if=$i" "of=${i%.jpg}.mp4" bs=$((ofs-4)) skip=1; \
done
Et pour supprimer des vidéos:
for i in MVIMG*.jpg; do \
ofs=$(grep -F --byte-offset --only-matching --text ftypmp4 "$i"); \
ofs=${ofs%:*}; \
[[ $ofs ]] && truncate -s $((ofs-4)) "$i"; \
done
La balise EXIF est utile, mais le décalage se fait par rapport à la fin du fichier. Le fichier mp4 est intégré à:
[file_size-micro_video_offset, file_size)
Par exemple:
$ exiftool -xmp:all MVIMG_123.jpg
XMP Toolkit : Adobe XMP Core 5.1.0-jc003
Micro Video : 1
Micro Video Version : 1
Micro Video Offset : 2107172
Micro Video Presentation Timestamp Us: 966280
$ python -c 'import os; print os.path.getsize("MVIMG_123.jpg") - 2107172'
3322791
$ dd if=MVIMG_123.jpg of=video.mp4 bs=3322791 skip=1
$ file video.mp4
video.mp4: ISO Media, MP4 v2 [ISO 14496-14]
La suggestion ci-dessus utilisant grep -F --byte-offset ...
et dd
ne fonctionne pas pour moi sur macOS High Sierra comme /usr/bin/grep
affiche un mauvais décalage - je suppose que cela donne le décalage de la "ligne" qui contient le mot ftypmp4
, c'est-à-dire la position du précédent LF caractère plus un. Je suppose que c'est faux, mais de toute façon, c'est ma solution:
for i in MVIMG*.jpg; do \
Perl -0777 -ne 's/^.*(....ftypmp4.*)$/$1/s && print' "$i" >"${i%.jpg}.mp4"; \
done
Cela utilise la capacité de Perl
à Slurp dans un fichier entier à la fois et à le traiter comme une grande chaîne. Sinon ftypmp4
avec au moins quatre octets de tête est présent, un fichier vide est créé, si plusieurs sont présents, le dernier est extrait.
De même, pour supprimer la vidéo de tous les fichiers:
for i in MVIMG*.jpg; do \
Perl -0777 -pi -e 's/^(.*?)....ftypmp4.*$/$1/s' "$i"; \
done
Cela utilise la fonction d'édition sur place de Perl
. Tout après la première occurrence de ftypmp4
avec ses quatre octets de tête est coupé. S'il n'y a aucune occurrence, le fichier est réécrit avec son contenu inchangé.
(Il peut être nécessaire ou non de définir PERLIO = raw dans l'environnement et/ou de désactiver les variables liées aux paramètres régionaux pour éviter une interprétation UTF-8, qui pourrait échouer pour les fichiers binaires qui contiennent des séquences d'octets qui violent les règles de composition UTF-8 Lors de mes tests avec divers fichiers MVIMG, aucun problème de ce type ne s'est produit.)