如何提取MVIMG的照片/视频组件?

rum*_*pel 8 exif image exiftool

Google Pixel 2以及其他手机可能具有覆盖“动态照片”的功能。这些被保存为MVIGM并且相对较大。

我正在寻找一种删除/提取视频的方法。

到目前为止,我发现了一个很有前途的exif标签

$ 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
Run Code Online (Sandbox Code Playgroud)

我以为视频可能以指定的偏移量出现,但这不起作用:

$ dd if=MVIMG_123.jpg of=video.mp4 bs=4032524 skip=1
$ file video.mp4
video.mp4: data
Run Code Online (Sandbox Code Playgroud)

是否有任何资源可以证明嵌入?甚至还有删除/提取视频的工具吗?

rum*_*pel 7

我确实找到了https://github.com/cliveontoast/GoMoPho,它扫描mp4标头,然后转储视频。

我们可以做同样的事情,ftypmp4从MP4头中扫描(实际文件比文件开头早4个字节):

因此要提取视频:

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
Run Code Online (Sandbox Code Playgroud)

并删除视频:

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
Run Code Online (Sandbox Code Playgroud)

  • 看起来 Android 12 中的情况发生了变化。我的 Pixel 4a 生成运动图像,其中 MP4 的偏移量为“ftypisom”。 (5认同)
  • 为了与两者兼容,请使用 `for i in PXL*.MP.jpg MVIMG*.jpg;` 和 `grep --byte-offset --only-matching --text "ftypmp4\|ftypisom" "$i"` (由于“or”模式,没有“-F”) (4认同)

小智 6

EXIF 标记很有用,但偏移量与文件末尾有关。mp4 文件嵌入在:

[file_size-micro_video_offset, file_size)
Run Code Online (Sandbox Code Playgroud)

例如:

$ 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]
Run Code Online (Sandbox Code Playgroud)


Jer*_*eek 6

帖子顶部的非 Perl shell 脚本可以在我的 Linux 系统上运行。我将它们合并到一个 shell 脚本中,该脚本保留输入文件(如 MVIMG_20191216_153039.jpg)并创建两个输出文件(如 IMG_20191216_153039.jpg 和 IMG_20191216_153039.mp4):

#!/bin/bash
# extract-mvimg: Extract .mp4 video and .jpg still image from a Pixel phone
# camera "motion video" file with a name like MVIMG_20191216_153039.jpg
# to make files like IMG_20191216_153039.jpg and IMG_20191216_153039.mp4
#
# Usage: extract-mvimg MVIMG*.jpg [MVIMG*.jpg...]

for srcfile
do
  case "$srcfile" in
  MVIMG_*_*.jpg) ;;
  *)
    echo "extract-mvimg: skipping '$srcfile': not an MVIMG*.jpg file?" 2>&1
    continue
    ;;
  esac

  # Get base filename: strip leading MV and trailing .jpg
  # Example: MVIMG_20191216_153039.jpg becomes IMG_20191216_153039
  basefile=${srcfile#MV}
  basefile=${basefile%.jpg}

  # Get byte offset. Example output: 2983617:ftypmp4
  offset=$(grep -F --byte-offset --only-matching --text ftypmp4 "$srcfile")
  # Strip trailing text. Example output: 2983617
  offset=${offset%:*}

  # If $offset isn't an empty string, create .mp4 file and
  # truncate a copy of input file to make .jpg file.
  if [[ $offset ]]
  then
    dd status=none "if=$srcfile" "of=${basefile}.mp4" bs=$((offset-4)) skip=1
    cp -ip "$srcfile" "${basefile}.jpg" || exit 1
    truncate -s $((offset-4)) "${basefile}.jpg"
  else
    echo "extract-mvimg: can't find ftypmp4 in $srcfile; skipping..." 2>&1
  fi
done
Run Code Online (Sandbox Code Playgroud)

status=none 抑制 dd 的“1+1 记录输入”和“1+1 记录输出”状态输出。如果你的 dd 不明白,你可以删除它。