You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何快速检测Android视频文件的指定元数据?

解决Android视频文件元数据提取需求(判断含音频、创建时间、缩略图)

我明白你在Android上提取特定视频元数据时遇到的困扰——原生MediaMetadataRetriever既慢又不可靠,而社区里现有的FFmpeg或原生API相关方案都没完全命中你的需求。下面我就针对你的三个核心需求,给出具体的实现方案,用FFmpegMediaMetadataRetriever来做,它虽然速度不算快,但胜在稳定可靠,能解决你的痛点。

一、判断视频是否包含音频

要判断视频里有没有音频流,我们可以通过FFmpegMediaMetadataRetriever提取所有流的信息,然后检查是否包含音频标识:

FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
try {
    retriever.setDataSource(videoFilePath);
    // 获取所有媒体流的描述信息
    String streamInfo = retriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_STREAMS);
    // 检查是否存在音频流
    boolean hasAudio = streamInfo != null && streamInfo.contains("audio");
} finally {
    // 务必释放资源,避免内存泄漏
    retriever.release();
}

这个方法的核心是METADATA_KEY_STREAMS返回的内容会包含所有流的类型、编码等信息,只要里面出现"audio"字段,就说明视频包含音频轨道。

二、获取视频创建日期和时间

视频的创建时间可能存在两个地方:一是视频文件内置的元数据,二是文件系统记录的创建/修改时间。我们优先读取内置元数据,因为它更准确;如果内置数据不存在,再 fallback 到文件系统信息:

FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
String creationTime = null;
try {
    retriever.setDataSource(videoFilePath);
    // 尝试读取视频内置的创建时间元数据
    creationTime = retriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_CREATION_TIME);
    
    // 如果内置元数据为空,读取文件系统的时间
    if (creationTime == null || creationTime.trim().isEmpty()) {
        File videoFile = new File(videoFilePath);
        long fileTimestamp = videoFile.lastModified();
        // 格式化时间为可读格式,可根据需求调整日期格式
        creationTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
            .format(new Date(fileTimestamp));
    }
} finally {
    retriever.release();
}

注意:不同Android版本对文件lastModified()的返回值可能有差异,部分设备返回的是文件修改时间,部分是创建时间,你可以根据目标设备进行适配测试。

三、提取视频缩略图

FFmpegMediaMetadataRetriever提取缩略图的稳定性远高于原生API,我们可以指定提取视频的第一帧(或任意时间点的帧)作为缩略图:

FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
Bitmap thumbnail = null;
try {
    retriever.setDataSource(videoFilePath);
    // 提取视频第一帧作为缩略图,OPTION_CLOSEST_SYNC确保获取关键帧
    thumbnail = retriever.getFrameAtTime(0, FFmpegMediaMetadataRetriever.OPTION_CLOSEST_SYNC);
    
    // 如果需要调整缩略图尺寸,可进行缩放
    if (thumbnail != null) {
        thumbnail = Bitmap.createScaledBitmap(thumbnail, 320, 240, true);
    }
} finally {
    retriever.release();
}

getFrameAtTime的第一个参数是时间戳(单位微秒),传入0就会提取第一帧;OPTION_CLOSEST_SYNC参数能保证获取到最接近指定时间的关键帧,避免出现黑屏或模糊的无效缩略图。


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

火山引擎 最新活动