Skip to content

Commit 5c72620

Browse files
committed
fix: 修复 getDuration 函数不支持 M4A/MP4 格式的问题
- 在 AacCodec.java 中新增 getDuration 方法 - 使用 MediaMetadataRetriever 获取时长,高效且无需解码 - 在 silk_codec.cpp 中添加 M4A/MP4 时长获取分支
1 parent 2eb277c commit 5c72620

2 files changed

Lines changed: 53 additions & 10 deletions

File tree

silk-codec/src/main/java/me/yun/silk/AacCodec.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,28 @@ public static int decodeM4aFile(String m4aPath, String pcmPath, AacCallback call
596596
return decodeAacFile(m4aPath, pcmPath, callback);
597597
}
598598

599+
public static long getDuration(String filePath) {
600+
android.media.MediaMetadataRetriever retriever = null;
601+
try {
602+
retriever = new android.media.MediaMetadataRetriever();
603+
retriever.setDataSource(filePath);
604+
String durationStr = retriever.extractMetadata(
605+
android.media.MediaMetadataRetriever.METADATA_KEY_DURATION);
606+
if (durationStr != null) {
607+
return Long.parseLong(durationStr);
608+
}
609+
} catch (Exception e) {
610+
} finally {
611+
if (retriever != null) {
612+
try {
613+
retriever.release();
614+
} catch (Exception e) {
615+
}
616+
}
617+
}
618+
return 0;
619+
}
620+
599621
public static String getErrorMessage(int code) {
600622
if (code == 0) return "成功";
601623
if (code >= -801 && code <= -802) return "AAC/M4A 解码错误 (文件读取失败)";

silk-codec/src/main/jni/silk_codec.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,21 +1525,22 @@ static long long getSilkDurationMs(const char *path) {
15251525
}
15261526

15271527
/**
1528-
* 获取音频时长 (单位:毫秒)
1529-
*
1530-
* 返回值: long (1秒 = 1000)
1528+
* 获取音频时长(毫秒)
1529+
*
1530+
* 支持格式: Silk, MP3, WAV, FLAC, OGG, M4A, MP4
1531+
* 返回值: 音频时长,单位毫秒
15311532
**/
15321533
JNIEXPORT jlong JNICALL Java_me_yun_silk_SilkCodec_getDuration(
15331534
JNIEnv *env, jobject thiz, jstring filePath) {
15341535
const char *path = env->GetStringUTFChars(filePath, 0);
15351536
int type = detectFileType(path);
15361537
jlong durationMs = 0;
1537-
1538+
15381539
switch (type) {
15391540
case FILE_TYPE_SILK:
15401541
durationMs = (jlong)getSilkDurationMs(path);
15411542
break;
1542-
1543+
15431544
case FILE_TYPE_MP3: {
15441545
drmp3 mp3;
15451546
if (drmp3_init_file(&mp3, path, NULL)) {
@@ -1549,7 +1550,7 @@ JNIEXPORT jlong JNICALL Java_me_yun_silk_SilkCodec_getDuration(
15491550
}
15501551
break;
15511552
}
1552-
1553+
15531554
case FILE_TYPE_WAV: {
15541555
drwav wav;
15551556
if (drwav_init_file(&wav, path, NULL)) {
@@ -1558,7 +1559,7 @@ JNIEXPORT jlong JNICALL Java_me_yun_silk_SilkCodec_getDuration(
15581559
}
15591560
break;
15601561
}
1561-
1562+
15621563
case FILE_TYPE_FLAC: {
15631564
drflac *pFlac = drflac_open_file(path, NULL);
15641565
if (pFlac) {
@@ -1567,7 +1568,7 @@ JNIEXPORT jlong JNICALL Java_me_yun_silk_SilkCodec_getDuration(
15671568
}
15681569
break;
15691570
}
1570-
1571+
15711572
case FILE_TYPE_OGG: {
15721573
int error;
15731574
stb_vorbis *v = stb_vorbis_open_filename(path, &error, NULL);
@@ -1578,12 +1579,32 @@ JNIEXPORT jlong JNICALL Java_me_yun_silk_SilkCodec_getDuration(
15781579
}
15791580
break;
15801581
}
1581-
1582+
1583+
case FILE_TYPE_M4A:
1584+
case FILE_TYPE_MP4: {
1585+
// 调用 Java 层 AacCodec 获取时长
1586+
jclass aacCodecClass = env->FindClass("me/yun/silk/AacCodec");
1587+
if (aacCodecClass != NULL) {
1588+
jmethodID getDurationMethod = env->GetStaticMethodID(
1589+
aacCodecClass,
1590+
"getDuration",
1591+
"(Ljava/lang/String;)J");
1592+
1593+
if (getDurationMethod != NULL) {
1594+
durationMs = (jlong)env->CallStaticLongMethod(
1595+
aacCodecClass,
1596+
getDurationMethod,
1597+
filePath);
1598+
}
1599+
}
1600+
break;
1601+
}
1602+
15821603
default:
15831604
durationMs = 0;
15841605
break;
15851606
}
1586-
1607+
15871608
env->ReleaseStringUTFChars(filePath, path);
15881609
return durationMs;
15891610
}

0 commit comments

Comments
 (0)