diff --git a/app/src/main/java/com/fongmi/android/tv/event/ErrorEvent.java b/app/src/main/java/com/fongmi/android/tv/event/ErrorEvent.java
index 944ae4726..6df01a3eb 100644
--- a/app/src/main/java/com/fongmi/android/tv/event/ErrorEvent.java
+++ b/app/src/main/java/com/fongmi/android/tv/event/ErrorEvent.java
@@ -56,7 +56,7 @@ public class ErrorEvent {
public String getMsg() {
if (type == Type.URL) return ResUtil.getString(R.string.error_play_url);
- if (type == Type.DRM) return ResUtil.getString(R.string.error_play_drm_scheme);
+ if (type == Type.DRM) return ResUtil.getString(R.string.error_play_drm);
if (type == Type.FLAG) return ResUtil.getString(R.string.error_play_flag);
if (type == Type.PARSE) return ResUtil.getString(R.string.error_play_parse);
if (type == Type.TIMEOUT) return ResUtil.getString(R.string.error_play_timeout);
diff --git a/app/src/main/java/com/fongmi/android/tv/player/Players.java b/app/src/main/java/com/fongmi/android/tv/player/Players.java
index 00432915d..7b5026030 100644
--- a/app/src/main/java/com/fongmi/android/tv/player/Players.java
+++ b/app/src/main/java/com/fongmi/android/tv/player/Players.java
@@ -48,6 +48,7 @@ import com.fongmi.android.tv.impl.ParseCallback;
import com.fongmi.android.tv.impl.SessionCallback;
import com.fongmi.android.tv.player.danmaku.DanPlayer;
import com.fongmi.android.tv.player.exo.CacheManager;
+import com.fongmi.android.tv.player.exo.ErrorMsgProvider;
import com.fongmi.android.tv.player.exo.ExoUtil;
import com.fongmi.android.tv.server.Server;
import com.fongmi.android.tv.utils.FileUtil;
@@ -77,6 +78,7 @@ public class Players implements Player.Listener, ParseCallback {
public static final int SOFT = 0;
public static final int HARD = 1;
+ private final ErrorMsgProvider provider;
private final AudioManager audioManager;
private final StringBuilder builder;
private final Formatter formatter;
@@ -110,6 +112,7 @@ public class Players implements Player.Listener, ParseCallback {
private Players(Activity activity) {
decode = Setting.getDecode();
builder = new StringBuilder();
+ provider = new ErrorMsgProvider();
runnable = () -> ErrorEvent.timeout(tag);
formatter = new Formatter(builder, Locale.getDefault());
audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
@@ -673,7 +676,7 @@ public class Players implements Player.Listener, ParseCallback {
@Override
public void onPlayerError(@NonNull PlaybackException error) {
Logger.t(TAG).e(error.errorCode + "," + url);
- if (retried()) ErrorEvent.extract(tag, error.getErrorCodeName());
+ if (retried()) ErrorEvent.extract(tag, provider.get(error));
else switch (error.errorCode) {
case PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW:
seekToDefaultPosition();
diff --git a/app/src/main/java/com/fongmi/android/tv/player/exo/ErrorMsgProvider.java b/app/src/main/java/com/fongmi/android/tv/player/exo/ErrorMsgProvider.java
new file mode 100644
index 000000000..5d19c72d6
--- /dev/null
+++ b/app/src/main/java/com/fongmi/android/tv/player/exo/ErrorMsgProvider.java
@@ -0,0 +1,74 @@
+package com.fongmi.android.tv.player.exo;
+
+import android.content.res.Resources;
+
+import androidx.media3.common.PlaybackException;
+import androidx.media3.exoplayer.mediacodec.MediaCodecRenderer;
+import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
+
+import com.fongmi.android.tv.App;
+import com.fongmi.android.tv.R;
+
+public class ErrorMsgProvider {
+
+ private final Resources resources;
+
+ public ErrorMsgProvider() {
+ this.resources = App.get().getResources();
+ }
+
+ public String get(PlaybackException e) {
+ if (e.getCause() instanceof MediaCodecRenderer.DecoderInitializationException e2) return custom(e2);
+ return resources.getString(getId(e.errorCode));
+ }
+
+ private String custom(MediaCodecRenderer.DecoderInitializationException e) {
+ if (e.codecInfo != null) return resources.getString(R.string.error_instantiating_decoder, e.codecInfo.name);
+ if (e.getCause() instanceof MediaCodecUtil.DecoderQueryException) return resources.getString(R.string.error_querying_decoders);
+ else if (e.secureDecoderRequired) return resources.getString(R.string.error_no_secure_decoder, e.mimeType);
+ else return resources.getString(R.string.error_no_decoder, e.mimeType);
+ }
+
+ private int getId(int errorCode) {
+ return switch (errorCode) {
+ case PlaybackException.ERROR_CODE_REMOTE_ERROR -> R.string.error_remote_error;
+ case PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW -> R.string.error_behind_live_window;
+ case PlaybackException.ERROR_CODE_TIMEOUT -> R.string.error_timeout;
+ case PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK -> R.string.error_failed_runtime_check;
+ case PlaybackException.ERROR_CODE_IO_UNSPECIFIED -> R.string.error_io_unspecified;
+ case PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED -> R.string.error_io_network_connection_failed;
+ case PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT -> R.string.error_io_network_connection_timeout;
+ case PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE -> R.string.error_io_invalid_http_content_type;
+ case PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS -> R.string.error_io_bad_http_status;
+ case PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND -> R.string.error_io_file_not_found;
+ case PlaybackException.ERROR_CODE_IO_NO_PERMISSION -> R.string.error_io_no_permission;
+ case PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED -> R.string.error_io_cleartext_not_permitted;
+ case PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE -> R.string.error_io_read_position_out_of_range;
+ case PlaybackException.ERROR_CODE_PARSING_CONTAINER_MALFORMED -> R.string.error_parsing_container_malformed;
+ case PlaybackException.ERROR_CODE_PARSING_MANIFEST_MALFORMED -> R.string.error_parsing_manifest_malformed;
+ case PlaybackException.ERROR_CODE_PARSING_CONTAINER_UNSUPPORTED -> R.string.error_parsing_container_unsupported;
+ case PlaybackException.ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED -> R.string.error_parsing_manifest_unsupported;
+ case PlaybackException.ERROR_CODE_DECODER_INIT_FAILED -> R.string.error_decoder_init_failed;
+ case PlaybackException.ERROR_CODE_DECODER_QUERY_FAILED -> R.string.error_decoder_query_failed;
+ case PlaybackException.ERROR_CODE_DECODING_FAILED -> R.string.error_decoding_failed;
+ case PlaybackException.ERROR_CODE_DECODING_FORMAT_EXCEEDS_CAPABILITIES -> R.string.error_decoding_format_exceeds_capabilities;
+ case PlaybackException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED -> R.string.error_decoding_format_unsupported;
+ case PlaybackException.ERROR_CODE_DECODING_RESOURCES_RECLAIMED -> R.string.error_decoding_resources_reclaimed;
+ case PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED -> R.string.error_audio_track_init_failed;
+ case PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED -> R.string.error_audio_track_write_failed;
+ case PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED -> R.string.error_audio_track_offload_write_failed;
+ case PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED -> R.string.error_audio_track_offload_init_failed;
+ case PlaybackException.ERROR_CODE_DRM_UNSPECIFIED -> R.string.error_drm_unspecified;
+ case PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED -> R.string.error_drm_provisioning_failed;
+ case PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR -> R.string.error_drm_content_error;
+ case PlaybackException.ERROR_CODE_DRM_LICENSE_ACQUISITION_FAILED -> R.string.error_drm_license_acquisition_failed;
+ case PlaybackException.ERROR_CODE_DRM_DISALLOWED_OPERATION -> R.string.error_drm_disallowed_operation;
+ case PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR -> R.string.error_drm_system_error;
+ case PlaybackException.ERROR_CODE_DRM_DEVICE_REVOKED -> R.string.error_drm_device_revoked;
+ case PlaybackException.ERROR_CODE_DRM_LICENSE_EXPIRED -> R.string.error_drm_license_expired;
+ case PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSOR_INIT_FAILED -> R.string.error_video_frame_processor_init_failed;
+ case PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED -> R.string.error_video_frame_processing_failed;
+ default -> R.string.error_unspecified;
+ };
+ }
+}
diff --git a/app/src/main/java/com/fongmi/android/tv/player/exo/TrackNameProvider.java b/app/src/main/java/com/fongmi/android/tv/player/exo/TrackNameProvider.java
index f4ca5f6b4..92e62585c 100644
--- a/app/src/main/java/com/fongmi/android/tv/player/exo/TrackNameProvider.java
+++ b/app/src/main/java/com/fongmi/android/tv/player/exo/TrackNameProvider.java
@@ -54,19 +54,13 @@ public class TrackNameProvider {
private String buildAudioChannelString(Format format) {
int channelCount = format.channelCount;
if (channelCount < 1) return "";
- switch (channelCount) {
- case 1:
- return resources.getString(R.string.exo_track_mono);
- case 2:
- return resources.getString(R.string.exo_track_stereo);
- case 6:
- case 7:
- return resources.getString(R.string.exo_track_surround_5_point_1);
- case 8:
- return resources.getString(R.string.exo_track_surround_7_point_1);
- default:
- return resources.getString(R.string.exo_track_surround);
- }
+ return switch (channelCount) {
+ case 1 -> resources.getString(R.string.exo_track_mono);
+ case 2 -> resources.getString(R.string.exo_track_stereo);
+ case 6, 7 -> resources.getString(R.string.exo_track_surround_5_point_1);
+ case 8 -> resources.getString(R.string.exo_track_surround_7_point_1);
+ default -> resources.getString(R.string.exo_track_surround);
+ };
}
private String buildLanguageOrLabelString(Format format) {
diff --git a/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java
index 27ec76608..18ad40874 100644
--- a/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java
+++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java
@@ -72,7 +72,7 @@ public class TVBus implements Source.Extractor, Listener {
private String check() throws Exception {
if (hls == null) return "";
if (!hls.startsWith("-")) return hls;
- throw new ExtractException(ResUtil.getString(R.string.error_play_code, hls));
+ throw new ExtractException(ResUtil.getString(R.string.error_play_url));
}
@Override
diff --git a/app/src/main/res/values-zh-rCN/error.xml b/app/src/main/res/values-zh-rCN/error.xml
new file mode 100644
index 000000000..39d439be1
--- /dev/null
+++ b/app/src/main/res/values-zh-rCN/error.xml
@@ -0,0 +1,44 @@
+
+ 发生未预期的错误
+ 发生远程错误
+ 已落后直播流过多
+ 操作超时
+ 发生内部播放器错误
+ 发生未知的 I/O 错误
+ 网络连接失败
+ 网络连接超时
+ 无效的服务器响应
+ 无法连接至服务器
+ 找不到文件
+ I/O 权限不足
+ 此内容需要安全的网络连接
+ 读取源数据失败
+ 媒体文件已损坏或格式不受支持
+ 流清单无效
+ 不支持此媒体容器格式
+ 不支持此流清单格式
+ 初始化媒体解码器失败
+ 找不到适合此格式的媒体解码器
+ 解码媒体时发生错误
+ 媒体画质超过设备能力上限
+ 此设备不支持该媒体格式
+ 解码资源已被系统回收
+ 初始化音轨失败
+ 写入音频数据失败
+ 写入 Offload 音频数据失败
+ 初始化 Offload 音轨失败
+ 发生未知的 DRM 错误
+ 设置设备 DRM 失败
+ 受保护的内容发生错误
+ 获取内容授权失败
+ 不允许此 DRM 操作
+ 发生 DRM 系统错误
+ 此设备的内容访问权已被撤销
+ 内容授权已过期
+ 初始化视频帧处理器失败
+ 处理视频帧时发生错误
+ 此设备未提供 %1$s 格式的解码器
+ 此设备未提供 %1$s 格式的安全解码器
+ 无法查询设备的解码器
+ 无法将解码器 %1$s 实例化
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 23d1a5ab7..8b0d72bf9 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -124,8 +124,7 @@
已经是最后一集了!
已经是第一集了!
播放地址解析失败
- 此设备不支持所需的 DRM scheme
- 错误代码:%s
+ 此设备不支持所需的 DRM scheme
播放地址加载失败
暂无线路数据
连接超时
diff --git a/app/src/main/res/values-zh-rTW/error.xml b/app/src/main/res/values-zh-rTW/error.xml
new file mode 100644
index 000000000..c2fec29d0
--- /dev/null
+++ b/app/src/main/res/values-zh-rTW/error.xml
@@ -0,0 +1,44 @@
+
+ 發生未預期的錯誤
+ 發生遠端錯誤
+ 已落後直播串流過多
+ 操作逾時
+ 發生內部播放器錯誤
+ 發生未知的 I/O 錯誤
+ 網路連線失敗
+ 網路連線逾時
+ 無效的伺服器回應
+ 無法連接至伺服器
+ 找不到檔案
+ I/O 權限不足
+ 此內容需要安全的網路連線
+ 讀取來源資料失敗
+ 媒體檔案已損毀或格式不受支援
+ 串流清單無效
+ 不支援此媒體容器格式
+ 不支援此串流清單格式
+ 初始化媒體解碼器失敗
+ 找不到適合此格式的媒體解碼器
+ 解碼媒體時發生錯誤
+ 媒體品質超過裝置能力上限
+ 此裝置不支援該媒體格式
+ 解碼資源已被系統收回
+ 初始化音軌失敗
+ 寫入音訊資料失敗
+ 寫入 Offload 音訊資料失敗
+ 初始化 Offload 音軌失敗
+ 發生未知的 DRM 錯誤
+ 設定裝置 DRM 失敗
+ 受保護的內容發生錯誤
+ 取得內容授權失敗
+ 不允許此 DRM 操作
+ 發生 DRM 系統錯誤
+ 此裝置的內容存取權已被撤銷
+ 內容授權已過期
+ 初始化影片影格處理器失敗
+ 處理影片影格時發生錯誤
+ 此裝置未提供 %1$s 格式的解碼器
+ 此裝置未提供 %1$s 格式的安全解碼器
+ 無法查詢裝置的解碼器
+ 無法將解碼器 %1$s 實例化
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 337d3b45a..79ae88de8 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -124,8 +124,7 @@
已經是最後一集了!
已經是第一集了!
播放網址解析失敗
- 本設備不支援所需的 DRM scheme
- 錯誤代碼:%s
+ 本設備不支援所需的 DRM scheme
播放網址載入失敗
暫無線路資料
連線逾時
diff --git a/app/src/main/res/values/error.xml b/app/src/main/res/values/error.xml
new file mode 100644
index 000000000..3ef1e7626
--- /dev/null
+++ b/app/src/main/res/values/error.xml
@@ -0,0 +1,44 @@
+
+ An unexpected error occurred
+ A remote error occurred
+ Fell too far behind the live stream
+ The operation timed out
+ An internal player error occurred
+ An unknown I/O error occurred
+ Network connection failed
+ Network connection timed out
+ Invalid server response
+ Unable to connect to the server
+ File not found
+ I/O permission denied
+ A secure connection is required for this content
+ Failed to read data from the source
+ The media file is corrupted or in an unsupported format
+ The stream manifest is invalid
+ The media container format is not supported
+ The stream manifest format is not supported
+ Failed to initialize the media decoder
+ Failed to find a suitable media decoder for the format
+ An error occurred while decoding the media
+ The media quality exceeds the device\'s capabilities
+ The media format is not supported by this device
+ Decoding resources were reclaimed by the system
+ Failed to initialize the audio track
+ Failed to write audio data
+ Failed to write offloaded audio data
+ Failed to initialize the offloaded audio track
+ An unknown DRM error occurred
+ Failed to configure DRM on this device
+ An error occurred with the protected content
+ Failed to acquire the content license
+ The requested DRM operation is not allowed
+ A DRM system error occurred
+ Access to this content has been revoked for this device
+ The content license has expired
+ Failed to initialize the video frame processor
+ An error occurred while processing a video frame
+ This device does not provide a decoder for %1$s
+ This device does not provide a secure decoder for %1$s
+ Unable to query device decoders
+ Unable to instantiate decoder %1$s
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 37462de20..e5de31e7e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -125,8 +125,7 @@
It\'s the last episode!
It\'s the first episode!
Unable to parse url
- This device does not support the required DRM scheme
- Error code: %s
+ This device does not support the required DRM scheme
Unable to load url
No flag data
Timed out