如何在Android上修改视频创建/修改日期?Mp4Composer裁剪后保留原日期
Android修改视频创建/修改日期 & Mp4Composer裁剪保留原元数据方案
一、Android端通用修改视频日期的方法
不管是要修改视频的创建日期还是修改日期,可以根据你的Android版本选择下面两种靠谱的方式:
1. API 29+(Android 10及以上):用MediaStore更新
Android 10开始限制直接操作文件,推荐用系统的MediaStore来修改媒体元数据,兼容性拉满:
fun updateVideoDate(context: Context, videoUri: Uri, targetDate: Long) { val values = ContentValues().apply { put(MediaStore.Video.Media.DATE_ADDED, targetDate / 1000) // 秒级时间戳 put(MediaStore.Video.Media.DATE_MODIFIED, targetDate / 1000) put(MediaStore.Video.Media.DATE_TAKEN, targetDate) // 拍摄日期,毫秒级 } context.contentResolver.update(videoUri, values, null, null) }
调用时传入原视频的Uri和你想要设置的日期时间戳就行。
2. API 28及以下:直接修改文件属性
低版本可以直接操作File对象的属性,简单直接:
fun updateVideoFileDate(videoFile: File, targetDate: Long) { // 修改文件的最后修改时间(对应系统显示的修改日期) videoFile.setLastModified(targetDate) // 如果要修改视频内部的拍摄元数据,可搭配MediaMetadataRetriever读取后再写入,或者用ExifInterface处理 val retriever = MediaMetadataRetriever() retriever.setDataSource(videoFile.path) // 这里可以读取原拍摄日期,修改后写回,注意视频的Exif兼容性 }
二、Mp4Composer裁剪后保留原视频日期的解决办法
我之前用Mp4Composer做裁剪时也踩过这个坑——输出视频的元数据日期默认是当前时间,查了官方API确实没有直接在编码阶段设置日期的接口,所以用「先存原日期,裁剪完成后再修改」的思路完美解决:
步骤1:获取原视频的日期元数据
先用MediaMetadataRetriever拿到原视频的拍摄/创建日期,优先取拍摄元数据,没有的话 fallback 到文件修改时间:
fun getOriginalVideoDate(videoPath: String): Long? { val retriever = MediaMetadataRetriever() return try { retriever.setDataSource(videoPath) // 先尝试拿拍摄日期 val dateTakenStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE_TAKEN) dateTakenStr?.toLong() ?: run { // 没有拍摄日期就拿文件修改时间 File(videoPath).lastModified() } } catch (e: Exception) { e.printStackTrace() null } finally { retriever.release() } }
步骤2:裁剪完成后同步原日期
按你原来的逻辑完成裁剪,在onCompleted回调里修改输出文件的日期:
Mp4Composer(sourcePath, outputPath) .trim(startTimeMs, endTimeMs) .listener(object : Mp4Composer.Listener { override fun onCompleted() { // 拿到原视频的日期 val originalDate = getOriginalVideoDate(sourcePath) originalDate?.let { // 根据系统版本选择修改方式 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // 先获取输出文件的ContentUri,再用MediaStore修改 val outputUri = getContentUriFromPath(context, outputPath) outputUri?.let { uri -> updateVideoDate(context, uri, it) } } else { updateVideoFileDate(File(outputPath), it) } } } override fun onProgress(progress: Double) {} override fun onFailed(exception: Exception) {} }) .start()
进阶:修改MP4内部元数据(比如moov里的creation_time)
如果需要让MP4文件本身的内部元数据(比如ISO BMFF标准里的creation_time字段)也同步原日期,就用mp4parser库来修改:
// Java示例,Kotlin可直接转译 File inputFile = new File(outputPath); File outputFile = new File(outputPath + "_temp.mp4"); IsoFile isoFile = new IsoFile(inputFile.getAbsolutePath()); Movie movie = new Movie(); for (TrackBox trackBox : isoFile.getMovieBox().getBoxes(TrackBox.class)) { movie.addTrack(new Mp4TrackImpl(trackBox)); } // 设置创建时间和修改时间为原视频日期 movie.setCreationTime(originalDate); movie.setModificationTime(originalDate); // 重新生成MP4文件 Container container = new DefaultMp4Builder().build(movie); FileOutputStream fos = new FileOutputStream(outputFile); FileChannel fc = fos.getChannel(); container.writeContainer(fc); fc.close(); fos.close(); // 替换原输出文件 inputFile.delete(); outputFile.renameTo(inputFile);
这个方法能直接修改MP4文件的底层元数据,确保不管用什么播放器查看,日期都是原视频的。
内容的提问来源于stack exchange,提问作者Adam Styrc




