Android 高保真音频播放组件,支持 DSD、MQA、SACD、CUE 分轨、网盘 / WebDAV 等场景。
implementation("io.github.qytech:audioplayer:1.2.5")
调用 seekTo(positionMs)(positionMs 为毫秒)可定位播放进度。连续快速调用时,库会保留最后一次定位目标并减少重复暂停、清空音频输出造成的播放停滞;显式调用 pause() 仍按暂停语义处理。
AudioProbe 会把容器元数据中的 syncedlyrics、lyrics 或 unsyncedlyrics 映射到 AudioMetadata.lyrics。没有内嵌歌词时该字段为 null。
val metadata = AudioProbe.probeFile("/storage/usb/Music/song.flac")
val embeddedLyrics: String? = metadata?.lyrics
歌词可能是带时间轴的 LRC 文本,也可能是纯文本;SDK 不负责把纯文本转换为时间轴。
存储设备拔出、网络卷卸载或连接中断时,先调用 requestAbort() 请求底层尽快退出正在进行的打开、读取、预加载或 Seek,再调用 forceRelease() 完成资源回收:
audioPlayer.requestAbort()
audioPlayer.forceRelease()
requestAbort() 是非阻塞请求,不能替代 forceRelease()。业务侧仍需在 Service 或其他明确的生命周期 owner 中持有播放器,并保证后续释放路径只执行一次。
seekTo(positionMs) 后可能停滞且无法自动恢复播放的问题,确保定位后的音频输出使用最新请求。io.github.qytech:audioplayer:1.2.5。seekTo(positionMs)(例如拖动进度条)时的处理,减少重复暂停、清空输出引发的播放停滞,并保留最后一次定位目标。io.github.qytech:audioplayer:1.2.4。AudioPlayer.requestAbort(),用于请求 Native 或流媒体播放器尽快中断阻塞中的打开、读取、预加载与 Seek。AudioMetadata.lyrics 返回。dtsPassthroughEnabled 参数(Boolean,默认 false),用于控制 DTS 音频是否通过 HDMI 透传。当 HDMI 支持 DTS 透传时,设置为 true 即可启用透传输出。mqaUnfoldEnabled 参数(Boolean,默认 true),用于控制 MQA 解码时是否自动展开至最高采样率。设置为 false 时可锁定输出采样率,避免部分 DAC 对展开后高采样率不支持的问题。特别说明
maxSampleRate默认值为0,升级后不会改变原有输出采样率策略。- 最大采样率是用户指定的输出策略,不代表播放器能够自动识别 DAC 的全部能力。如果 DAC 不支持指定采样率,播放器会进入错误状态并通过
PlayerListener.onError(...)通知业务层,不会导致应用崩溃。
forceRelease,防止 USB 播放中拔出设备时闪退data class MediaInfo(
val sourceId: String,
val sampleRate: Int,
val channels: Int,
val bitrate: Long,
val bitDepth: Int,
val format: String,
val title: String = "Unknown Title",
val artist: String = "Unknown Artist",
val album: String = "Unknown Album",
// MQA 状态:0=非 MQA;非 0=已识别/认证
val mqaUiState: Int = 0,
// MQA 原始采样率 (Hz)
val mqaOriginalRate: Int = 0,
// MQA 展开后的输出采样率 (Hz)
val mqaOutputRate: Int = 0,
)
注:0.9.6 升级了 Gradle 版本,此版本暂时回退
webdav 播放时失败的问题DST 二次封装格式的音频检测不全问题playerManager.setNextMediaSource(
DefaultMediaSource(
uri = nextNextAudio.sourceId
)
)
AudioPlayerFactory 播放 CUE 时同时传入 Offset 和 CUE+TrackId 时可能出现播放异常PlayerListener 添加了 onMetadata(mediaInfo: MediaInfo) 接口data class MediaInfo(
val sampleRate: Int,
val channels: Int,
val bitrate: Long,
val bitDepth: Int,
val format: String,
val title: String = "Unknown Title",
val artist: String = "Unknown Artist",
val album: String = "Unknown Album",
)
val webDavUrl = "https://dav.jianguoyun.com/dav/音频测试/左右声道测试_PCM_44.1k.wav"
val webDavUser = ""
val webDavPwd = ""
AudioProbe.probeFile(webDavUrl, webDavUser = webDavUser, webDavPwd = webDavPwd)
AudioProbe.probe(webDavUrl, ScanProfile.WebDav(webDavUser, webDavPwd))
DffAudioFrame 被移除但其他库仍在使用的问题PlayerListener 合并了之前的 OnProgressListener 和 OnPlaybackStateChangeListenerpublic interface PlayerListener {
fun onPrepared()
fun onProgress(track: Int, current: Long, total: Long, progress: Float)
fun onError(code: Int, msg: String)
fun onComplete()
fun onStateChanged(state: PlaybackState)
}