















以前在博客里分享出游照片,基本就是直接放图片,偶尔放几张 GIF 动图。
最近突然觉得,既然现在手机拍照已经越来越喜欢带“动态”了,网页上是不是也可以换一种展示方式?
于是就想到了苹果的 Live Photos(实况照片) 和安卓手机的 Motion Photo(动态照片)。
这种方式其实挺适合用在游记里。一张照片本身还是照片,但又可以在需要的时候动起来,比 GIF 看起来更自然,也不用为了一个几秒钟的小动画单独放一张 GIF。
于是这段时间就折腾了一下。
苹果的 Live Photos,从展示效果上理解,其实就是一张封面照片加上一小段视频,只不过系统把两者组织成了一个完整的“实况照片”。
而 Android 的 Motion Photo 又有点不一样。
从文件上看,它通常还是一张 JPG 图片,只是在图片数据后面附加了一段视频数据,同时通过 XMP 等元数据记录这段视频的位置、长度等信息。
GitHub 上其实已经有不少类似的项目,基本都是用这种方式在网页上模拟动态照片。
这个方式反而是最好实现的,图片和视频各自独立,浏览器直接播放视频就行。
一开始看了不少 Live Photos 的实现,发现很多项目基本就是照着苹果的交互来做。
但我觉得网页端其实可以稍微有点自己的区别。
手机上的动态照片,毕竟是手机相册里的一个功能,声音主要跟着手机本身的静音、媒体音量等设置走。
但到了 PC 网页上,情况就不太一样了。没有声音控制总感觉少了点什么,所以我参考了一下 Windows 11 自带“照片”应用播放动态照片时的交互,做了一套比较适合网页的方式。
目前的想法是:
而且这些东西我都做成了配置项,比如是否显示声音按钮、是否默认开启声音、是否开启鼠标移入自动播放。
所以如果以后觉得鼠标移入播放太积极了,也可以直接关掉。
我们先来看看实际的效果。
| ↑ JPG + MP4(H.264) | ↑ JPG + MP4(H.265) |
| ↑ JPG + MP4(H.264) + 无声音 | ↑ JPG + MOV |
我自己测试下来,JPG + 有声音的MP4 在各个浏览器下效果基本正常,H.265编码的在FireFox下播放稳定性差一些;JPG + 无声音的MP4 在 FireFox 下播放声音图标会置灰,但是在 Chrome/Edge 则还是和有声音的一样;JPG + MOV 在 FireFox 下不能播放声音,声音图标会置灰。
这里还有一个比较容易碰到的问题。
假设设置成了默认开启声音。
第一次打开网页,什么都没有操作,这时候直接把鼠标移到动态照片的 LIVE 图标上。
视频可以播放,但不一定会有声音。这不是代码的问题,而是浏览器的自动播放策略。
现代浏览器通常会限制页面在用户没有进行交互之前自动播放带声音的媒体。鼠标移入本身并不等同于一次可靠的“用户激活”。
所以第一次进入页面时,即使程序设置的是“开启声音”,浏览器也可能只允许它静音播放。
这时候只需要在页面任意位置点击一下,再把鼠标移到动态照片上,声音就可以正常播放了。
所以现在这套逻辑实际上是:默认可以开声音,但浏览器说不让开,那就先静音播放;等用户真正点击过页面以后,再恢复声音。
这个细节在 PC 网页上还挺有意思的。
既然是自己准备视频,那另外一个问题就是视频编码。
H.264 基本还是比较省心的选择,H.265,也就是 HEVC,现在主流浏览器其实也并不是不能播放。
我实际测试下来,H.264 和 H.265 视频在 Chrome、Edge、Firefox 里都可以正常播放。
所以这里倒不用简单地说成“H.265 浏览器不支持”。
如果只是自己准备一段视频放到网页里,我还是更倾向于 H.264 + MP4。
原因也很简单:不是因为 H.265 一定不能播放,而是 H.264 的兼容性更好。
毕竟自己做的话,没必要给后面增加不必要的变量。
到这里,“封面 + 视频”这一套其实已经基本没什么问题了。
但我又想了一下:既然手机本身已经可以拍 Motion Photo,为什么还要每次自己准备一张图片和一段视频?
能不能直接读取手机拍出来的动态照片?
于是开始了第二轮折腾。
这次主要就是解析 JPG 里面的 XMP 信息,找到 Motion Photo 对应的视频数据,再把 JPEG 和后面的 MP4 数据分离出来。
实际做下来,比想象中麻烦一些。因为不同手机、不同版本的动态照片,文件结构并不是完全一样。
不过经过 WorkBuddy 的加持,也基本把这一套东西折腾出来了。
手机拍完动态照片,直接把原始文件丢给网页,不需要再提前拆成 JPG 和 MP4。
但做到这里以后,我又拿小米、华为手机拍出来的动态照片原图,在 Chrome、Edge、Firefox 下分别测试了一遍。
这时候情况就不太一样了。
Chrome 的整体表现最好,我测试的小米和华为动态照片基本都能够正常播放。
Edge 稍微有点奇怪。华为以及部分小米手机拍出来的动态照片,虽然视频有声音,但画面会出现黑屏。
Firefox 的表现则更加挑文件。同样是手机直接拍出来的动态照片,有些可以正常播放,有些则无法正常播放。
这里需要说明一下,这并不能简单归结为 H.264 和 H.265 的区别。
因为我前面单独测试过,H.264 和 H.265 视频本身,在这几个浏览器里都可以播放。
真正出现差异的,是手机原始 Motion Photo 这个文件本身。
不同手机生成动态照片的方式并不完全一样,在视频编码、封装方式,以及图片和视频数据的组合方式上,都可能存在差异。
所以:视频能不能播放是一回事,手机拍出来的这张动态照片能不能被浏览器正常解析和播放,是另一回事。
这也是直接读取手机原始动态照片以后才发现的问题。
真正拿手机拍了几张动态照片测试之后,发现最现实的问题其实不是代码。
而是:太大了。
手机直接拍出来的动态照片,文件大小基本都是 10MB 以上。一张还好。如果一篇游记放上十几张,就非常影响页面的加载速度了。
这也是目前我觉得“直接把手机原始动态照片扔到博客里”最大的问题。
能实现,不代表适合直接用。所以我又试了一种方式。
自己准备:一张普通图片 + 一段 H.264 编码的 MP4
然后再把它们合成一张 Motion Photo。
这样就可以自己控制:
我自己合成测试了一下,效果反而挺不错。
同样的动态照片,在 Chrome、Edge、Firefox 下都可以正常播放。
这也让我觉得,如果以后真的要在博客里大量使用动态照片,自己压缩、自己合成可能才是比较实际的方案。
手机原图可以留着自己保存,放到网页上的版本则专门做一次压缩。
这样既保留了动态照片的效果,也不会让网页因为一张照片就下载十几 MB。
对于博客里的游记来说,我觉得这个形式其实挺合适。
毕竟很多时候一张照片已经能够说明问题,但像瀑布、溪流、孩子玩水这些场景,稍微动个几秒,感觉还是完全不一样。
以后出去玩拍到合适的照片,应该会多一种选择。
不再只是:照片或者 GIF。还可以是这种:会动的照片。
目前我做的这个小 Demo,已经把两种方式放到了一起:
一张普通图片 + 独立视频 和 一张 JPG 动态照片,直接读取里面的视频。
默认开启声音
默认关闭声音
想研究一下不同品牌手机拍摄的动态照片,由于来源不多,如果大家有合适的动态照片原图,也可以发我邮箱:weisayok[at]aliyun.com,图片可以打个压缩包,防止被修改,感谢。
网上不少拆分和合并动态图片的服务,以下是我测试用到的。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。