使用 Android 播放 .flac 媒体
Playing .flac media with Android
我正在尝试 Android 设备可以播放的不同格式。 This page at the docs 指定 Android 平台支持的所有媒体编解码器。请注意,它还包括 flac
编解码器(.flac 容器)。我只是用一个非常原型的 class 来查看媒体是否可以播放。
下面是我的activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="timre-CCBYNC.flac"
android:onClick="playMusic"
/>
</LinearLayout>
还有我非常简单的 MainActivity.java
文件:
package com.hbad.www.testmusic_playaudio;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void playMusic(View view)throws IOException {
Button passed_btn = (Button)view;
AssetFileDescriptor afd = getAssets().openFd(passed_btn.getText().toString());
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
}
}
但是,当我尝试播放 flac
文件时,出现以下错误:
11-13 13:04:19.087 16332-16332/com.hbad.www.testmusic_playaudio E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.hbad.www.testmusic_playaudio, PID: 16332
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:4496)
at android.view.View$PerformClick.run(View.java:18603)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:4496)
at android.view.View$PerformClick.run(View.java:18603)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
at android.content.res.AssetManager.openAssetFd(Native Method)
at android.content.res.AssetManager.openFd(AssetManager.java:343)
at com.hbad.www.testmusic_playaudio.MainActivity.playMusic(MainActivity.java:24)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:4496)
at android.view.View$PerformClick.run(View.java:18603)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
现在,我确实看到一个错误,该文件无法作为文件描述符打开,因为它可能被压缩了。我知道 flac
是一种无损压缩,所以它可以工作,但我对这里的逻辑不满意。既然mp3
也是压缩格式怎么播放呢?
您可以为某些扩展禁用资产压缩,您可以将其添加到您的 build.gradle
android {
aaptOptions {
noCompress "your_extension"
}
}
禁用 flac 文件扩展名的压缩。
android {
aaptOptions {
noCompress 'flac'
}
}
对于多个扩展
android {
aaptOptions {
noCompress 'flac', 'other extensions'
}
}
作为准备 APK 的一部分,aapt 有选择地压缩各种资产以在设备上保存 space。 aapt 确定哪些资产需要压缩的方式是通过它们的文件扩展名。从 aapt 源代码 Package.cpp 默认情况下,这些文件扩展名免于压缩。
{
".jpg", ".jpeg", ".png", ".gif",
".wav", ".mp2", ".mp3", ".ogg", ".aac",
".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".amr", ".awb", ".wma", ".wmv"
}
我正在尝试 Android 设备可以播放的不同格式。 This page at the docs 指定 Android 平台支持的所有媒体编解码器。请注意,它还包括 flac
编解码器(.flac 容器)。我只是用一个非常原型的 class 来查看媒体是否可以播放。
下面是我的activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="timre-CCBYNC.flac"
android:onClick="playMusic"
/>
</LinearLayout>
还有我非常简单的 MainActivity.java
文件:
package com.hbad.www.testmusic_playaudio;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void playMusic(View view)throws IOException {
Button passed_btn = (Button)view;
AssetFileDescriptor afd = getAssets().openFd(passed_btn.getText().toString());
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
}
}
但是,当我尝试播放 flac
文件时,出现以下错误:
11-13 13:04:19.087 16332-16332/com.hbad.www.testmusic_playaudio E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.hbad.www.testmusic_playaudio, PID: 16332
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:4496)
at android.view.View$PerformClick.run(View.java:18603)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:4496)
at android.view.View$PerformClick.run(View.java:18603)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
at android.content.res.AssetManager.openAssetFd(Native Method)
at android.content.res.AssetManager.openFd(AssetManager.java:343)
at com.hbad.www.testmusic_playaudio.MainActivity.playMusic(MainActivity.java:24)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:4496)
at android.view.View$PerformClick.run(View.java:18603)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
现在,我确实看到一个错误,该文件无法作为文件描述符打开,因为它可能被压缩了。我知道 flac
是一种无损压缩,所以它可以工作,但我对这里的逻辑不满意。既然mp3
也是压缩格式怎么播放呢?
您可以为某些扩展禁用资产压缩,您可以将其添加到您的 build.gradle
android {
aaptOptions {
noCompress "your_extension"
}
}
禁用 flac 文件扩展名的压缩。
android {
aaptOptions {
noCompress 'flac'
}
}
对于多个扩展
android {
aaptOptions {
noCompress 'flac', 'other extensions'
}
}
作为准备 APK 的一部分,aapt 有选择地压缩各种资产以在设备上保存 space。 aapt 确定哪些资产需要压缩的方式是通过它们的文件扩展名。从 aapt 源代码 Package.cpp 默认情况下,这些文件扩展名免于压缩。
{
".jpg", ".jpeg", ".png", ".gif",
".wav", ".mp2", ".mp3", ".ogg", ".aac",
".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".amr", ".awb", ".wma", ".wmv"
}