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

时间:2018-11-01 16:04:02

标签: image exif 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

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

$ dd if=MVIMG_123.jpg of=video.mp4 bs=4032524 skip=1
$ file video.mp4
video.mp4: data

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

4 个答案:

答案 0 :(得分:4)

我确实发现https://github.com/cliveontoast/GoMoPho会扫描mp4标头,然后转储视频。

我们可以做同样的事情,从MP4头扫描ftypmp4(实际文件比文件早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

并删除视频:

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

答案 1 :(得分:2)

EXIF标记很有用,但偏移量是相对于文件结尾的。 mp4文件嵌入在:

nav li {
   float: left;
}
nav {
   display: inline-block;
}

例如:

[file_size-micro_video_offset, file_size)

答案 2 :(得分:0)

上面的使用grep -F --byte-offset ...dd的建议在macOS High Sierra上对我不起作用,因为/usr/bin/grep输出错误的偏移量-我猜它会产生“行”的偏移量包含单词ftypmp4,即前一个LF字符的位置加一个。我可能猜错了,但是无论如何,这是我的解决方案:

for i in MVIMG*.jpg; do \
    perl -0777 -ne 's/^.*(....ftypmp4.*)$/$1/s && print' "$i" >"${i%.jpg}.mp4"; \
done

这使用perl一次吞入整个文件并将其视为一个大字符串的功能。如果不存在带有至少四个前导字节的ftypmp4,则创建一个空文件,如果存在多个,则提取最后一个文件。

类似地,要从所有文件中删除视频:

for i in MVIMG*.jpg; do \
    perl -0777 -pi -e 's/^(.*?)....ftypmp4.*$/$1/s' "$i"; \
done

这使用perl的就地编辑功能。 ftypmp4第一次出现后,其前四个字节的所有内容都会被切断。如果没有出现,则文件的内容将保持不变。

(可能需要也可能不需要在环境中设置PERLIO = raw和/或未设置与语言环境相关的变量,以避免UTF-8解释,这对于二进制文件(碰巧包含违反UTF- 8个合成规则。在我对各种MVIMG文件的测试中,都没有发生此类问题。)

答案 3 :(得分:0)

文章顶部的non-perl shell脚本可以在我的Linux系统上使用。我将它们合并到一个外壳程序脚本中,该脚本保留了输入文件(如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

status = none禁止从dd输出“ 1 + 1条记录输入”和“ 1 + 1条记录输出”状态。如果您的dd不懂,可以将其删除。