You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Exif-js从MP4视频文件中获取EXIF信息

问题:Exif-js无法读取MP4文件的EXIF数据

我尝试用Exif-js从MP4文件提取EXIF数据,但视频部分完全没效果,图片部分代码运行正常。

根据Exif-js官方文档,调用EXIF.enableXmp()可以支持XMP,我已经在获取MP4的EXIF数据前执行了这个方法。我知道XMP是视频文件存储元数据(类似EXIF)的格式。

请问怎么修复这段代码?谢谢!

更新:
视频元数据一般没有"Make"和"Model"字段,所以我换成了JPG和MP4都通用的GPS Latitude字段。下面是exiftool的输出结果:

$ exiftool test.jpg | grep "GPS Latitude"
GPS Latitude Ref                : South
GPS Latitude                    : 3 deg 8' 50.92" S

$ exiftool test.mp4 | grep "GPS Latitude"
GPS Latitude                    : 24 deg 19' 55.51" N
GPS Latitude Ref                : North

原测试代码:

<!Doctype html>
<head>
<title> EXIF movies test </title>
</head>

<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
<script type=text/javascript>
window.onload=getExif;

function getExif() {
    var img1 = document.getElementById("img1");
    EXIF.getData(img1, function() {
        var make = EXIF.getTag(this, "Make");
        var model = EXIF.getTag(this, "Model");
        var GpsLatitude = EXIF.getTag(this, "GPSLatitude");
        var makeAndModel = document.getElementById("makeAndModel");
        makeAndModel.innerHTML = `${make} ${model} ${GpsLatitude}`;
    });

    EXIF.enableXmp();
    var img2 = document.getElementById("img2");
    EXIF.getData(img2, function() {
        var myData =this;
        var make = "A";  //EXIF.getTag(this, "Make");
        var model = "B"; //EXIF.getTag(this, "Model");
        var GpsLatitude = EXIF.getTag(this, "GPSLatitude");
        var makeAndModel2 = document.getElementById("makeAndModel2");
        makeAndModel2.innerHTML = `${make} ${model} ${GpsLatitude}`;

        var allMetaData = EXIF.getAllTags(this);
        var allMetaDataSpan = document.getElementById("allMetaDataSpan");
        allMetaDataSpan.innerHTML = JSON.stringify(allMetaData, null, "\t");
    });
}
</script>

<body>
<img width=400 src="test.jpg" id="img1" />
<pre>Make and model: <span id="makeAndModel"></span></pre>
<br/>

<!--<img src="test.mp4" id="img2" />-->

<!--
<video id="img2" autoplay muted width="560" height="315" controls >
  <source src="test.mp4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></video>
-->

<iframe id= "img2" width="560" height="315" src="test.mp4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


<pre>Make and model2: <span id="makeAndModel2"></span></pre>
<pre id="allMetaDataSpan"></pre>

<br/>

</body>
</html>

修复方案

1. 核心问题

Exif-js仅针对**<img>元素**设计,没有实现对<video>或<iframe>的元数据读取逻辑,所以直接调用EXIF.getData()处理这些元素不会生效。

2. 正确实现:通过File API读取二进制数据

要读取视频元数据,需直接获取文件的二进制内容,再交给Exif-js解析。修改后的代码如下:

<!Doctype html>
<head>
<title> EXIF movies test </title>
</head>

<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
<script type=text/javascript>
window.onload=init;

function init() {
    // 保留原有图片处理逻辑
    var img1 = document.getElementById("img1");
    EXIF.getData(img1, function() {
        var make = EXIF.getTag(this, "Make");
        var model = EXIF.getTag(this, "Model");
        var GpsLatitude = EXIF.getTag(this, "GPSLatitude");
        var makeAndModel = document.getElementById("makeAndModel");
        makeAndModel.innerHTML = `${make} ${model} ${GpsLatitude}`;
    });

    // 处理视频元数据
    loadVideoMetadata();
}

function loadVideoMetadata() {
    EXIF.enableXmp();
    // 用XHR获取视频文件二进制数据
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'test.mp4', true);
    xhr.responseType = 'arraybuffer';

    xhr.onload = function() {
        if (this.status === 200) {
            // 将ArrayBuffer转为Blob供Exif-js处理
            const blob = new Blob([this.response]);
            EXIF.getData(blob, function() {
                const gpsLat = EXIF.getTag(this, "GPSLatitude");
                const gpsLatRef = EXIF.getTag(this, "GPSLatitudeRef");
                const videoInfo = document.getElementById("makeAndModel2");
                videoInfo.innerHTML = `GPS纬度: ${gpsLat} ${gpsLatRef}`;

                // 打印所有可用元数据
                const allMetaData = EXIF.getAllTags(this);
                const metaSpan = document.getElementById("allMetaDataSpan");
                metaSpan.innerHTML = JSON.stringify(allMetaData, null, "\t");
            });
        }
    };
    xhr.send();
}
</script>

<body>
<img width=400 src="test.jpg" id="img1" />
<pre>图片信息: <span id="makeAndModel"></span></pre>
<br/>

<video width="560" height="315" controls >
  <source src="test.mp4" type="video/mp4"></video>

<pre>视频GPS信息: <span id="makeAndModel2"></span></pre>
<pre id="allMetaDataSpan"></pre>

<br/>
</body>
</html>

3. 注意事项

  • 跨域限制:如果视频文件和页面不在同一域名,需服务器配置CORS允许跨域请求,否则XHR会失败。
  • Exif-js的局限性:它不是专门的视频元数据解析库,对MP4中XMP的支持可能不完全,若需要更稳定的解析,建议使用专门库(如exifr)。
  • 字段匹配:视频中的元数据Tag名称可能和图片略有差异,可通过EXIF.getAllTags()查看所有可用字段后再针对性获取。

内容的提问来源于stack exchange,提问作者stackunderflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:38:09