多语言

更新时间:
复制 MD 格式

本地化系统(Locale)是 AliPlayerKit 的国际化支撑模块。它通过统一的语言管理器 LocaleManager,提供自动跟随系统语言、手动语言切换、自定义 Provider 注入等核心能力,使播放器 UI 文案能够灵活适配多语言场景。

概念介绍

什么是 LocaleManager?

LocaleManager 是 AliPlayerKit 的内置国际化管理单例,负责播放器所有 UI 文案(按钮文本、错误提示、设置项标题等)的本地化查询。它采用解析链(Resolution Chain)机制,按优先级逐级查找翻译:

Custom Provider → activeBundle(手动/系统) → sdkBundle fallback → Key 本身

核心价值

价值

说明

零配置可用

内置中/英两种语言,自动跟随系统语言,无需任何初始化

灵活切换

支持跟随系统和手动指定两种模式,满足不同业务需求

可扩展

通过 LocaleProvider 协议注入自定义翻译,优先级最高

实时通知

语言切换后通过 LocaleDidChangeNotification 通知所有 UI 刷新

语言模式

模式

枚举值

说明

跟随系统(默认)

LocaleModeSystem

自动使用系统首选语言

手动指定

LocaleModeManual

使用开发者指定的语言代码

功能特性

默认行为(零配置)

AliPlayerKit 开箱即用,无需编写任何代码即可支持多语言:

  • 内置简体中文和英文两种语言。

  • 播放器 UI 文案自动跟随系统语言切换,无需任何初始化或 API 调用。

  • 用户在系统「设置 → 通用 → 语言与地区」中切换语言后,播放器文案自动切换。

  • 如果系统语言不在内置支持范围内,自动回退到默认语言(简体中文)。

内置语言

语言

语言代码

资源目录

简体中文(默认)

zh-Hans

PlayerKit.bundle/zh-Hans.lproj/Localizable.strings

英文

en

PlayerKit.bundle/en.lproj/Localizable.strings

说明

对于大多数只需要中英文支持的应用,无需调用任何 API,集成 AliPlayerKit 即可。

内置文案Key分类

分类

Key 常量前缀

示例 Key

播放状态

LocaleKeyPlayState*

LocaleKeyPlayStateLoadingLocaleKeyPlayStateErrorCodeLabel

底部控制栏

LocaleKeyBottomBar*

LocaleKeyBottomBarSpeedLocaleKeyBottomBarQuality

倍速提示

LocaleKeySpeedPlayingHint

倍速播放中提示文案

设置菜单

LocaleKeySetting*

LocaleKeySettingMenuTitleLocaleKeySettingSpeed

镜像模式

LocaleKeyMirror*

LocaleKeyMirrorNoneLocaleKeyMirrorHorizontal

缩放模式

LocaleKeyScale*

LocaleKeyScaleFitXYLocaleKeyScaleCenterCrop

日志面板

LocaleKeyLogPanel*

LocaleKeyLogPanelTitleHideLocaleKeyLogPanelClear

横屏提示

LocaleKeyLandscapeHint*

LocaleKeyLandscapeHintFullscreen

通用

LocaleKeyUnknown

通用"未知"文案

说明

所有 Key 常量定义在 LocaleKeys.h 中,使用类型化常量确保编译期检查和 IDE 自动补全。

使用方式

跟随系统语言(默认,无需代码)

集成 AliPlayerKit 后,播放器文案自动根据系统语言显示对应翻译:

// 无需任何配置,播放器 UI 文案自动跟随系统语言
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
// 此时如系统为英文,所有 UI 文案自动显示英文

手动指定语言

当需要在应用内提供语言切换入口、不跟随系统语言时:

// 强制切换到英文
[AliPlayerKit setLanguageCode:@"en"];

// 强制切换到简体中文
[AliPlayerKit setLanguageCode:@"zh-Hans"];
说明

调用 setLanguageCode: 后,localeMode 自动切换为 LocaleModeManual,并发送 LocaleDidChangeNotification 通知,已绑定的插槽会自动刷新文案。

恢复跟随系统

手动指定语言后,如需恢复为跟随系统:

// 清除手动设定,localeMode 恢复为 LocaleModeSystem
[AliPlayerKit resetLocaleToSystemLanguage];

查询当前语言

// 获取当前生效的语言代码
NSString *currentLang = [AliPlayerKit currentLanguageCode];
NSLog(@"当前语言: %@", currentLang); // 如 "zh-Hans" 或 "en"

监听语言变更

通过 NSNotification 监听语言切换事件:

// 注册通知
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(localeDidChange:)
                                             name:LocaleDidChangeNotification
                                           object:nil];

// 处理语言变更
- (void)localeDidChange:(NSNotification *)notification {
    NSString *newLanguage = notification.userInfo[LocaleLanguageCodeKey];
    NSLog(@"语言已切换为: %@", newLanguage);
    // 刷新自定义 UI 文案
    [self refreshCustomUI];
}

// 不再需要时移除
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:LocaleDidChangeNotification
                                                  object:nil];
}

自定义开发

LocaleProvider 协议

LocaleProvider 定义了自定义翻译的注入接口:

@protocol LocaleProvider <NSObject>

@optional

/// 为指定 key 返回本地化字符串。
/// 返回 nil 表示不处理此 key,由 SDK 内部 fallback 继续解析。
- (nullable NSString *)localizedStringForKey:(NSString *)key;

@end
说明

localizedStringForKey: 是 @optional 方法。LocaleManager 在调用前会通过 respondsToSelector: 检查。

注入自定义 Provider

通过实现 LocaleProvider 协议,可以在不修改资源文件的情况下自定义任何翻译:

// 1. 定义自定义 Provider
@interface MyLocaleProvider : NSObject <LocaleProvider>
@end

@implementation MyLocaleProvider

- (nullable NSString *)localizedStringForKey:(NSString *)key {
    // 自定义特定 key 的翻译
    if ([key isEqualToString:LocaleKeyPlayStateLoading]) {
        return @"视频缓冲中,请稍候...";
    }
    if ([key isEqualToString:LocaleKeySettingSpeed]) {
        return @"播放倍率";
    }
    // 返回 nil 表示不处理此 key,由 SDK fallback 链继续解析
    return nil;
}

@end

// 2. 注入 Provider
MyLocaleProvider *provider = [[MyLocaleProvider alloc] init];
[AliPlayerKit setLocaleProvider:provider];
说明

LocaleManager 以弱引用持有 Provider,调用方需自行保持 Provider 实例的生命周期。

新增语言支持

当需要新增 AliPlayerKit 尚未内置的语言(如日语)时,通过自定义 Provider 实现全量翻译:

@interface JapaneseLocaleProvider : NSObject <LocaleProvider>
@property (nonatomic, strong) NSDictionary<NSString *, NSString *> *translations;
@end

@implementation JapaneseLocaleProvider

- (instancetype)init {
    self = [super init];
    if (self) {
        _translations = @{
            LocaleKeyPlayStateLoading: @"読み込み中...",
            LocaleKeyPlayStateErrorCodeLabel: @"エラーコード",
            LocaleKeyPlayStateErrorMessageLabel: @"エラーメッセージ",
            LocaleKeyBottomBarSpeed: @"速度",
            LocaleKeyBottomBarQuality: @"画質",
            LocaleKeySettingMenuTitle: @"設定",
            LocaleKeySettingSpeed: @"再生速度",
            LocaleKeySettingLoop: @"ループ再生",
            LocaleKeySettingMute: @"ミュート",
            LocaleKeySettingQuality: @"画質",
            // ... 全量翻译所有 LocaleKeys.h 中的 key
        };
    }
    return self;
}

- (nullable NSString *)localizedStringForKey:(NSString *)key {
    return self.translations[key];
}

@end

// 注入日语 Provider(需自行持有实例)
self.jaProvider = [[JapaneseLocaleProvider alloc] init];
[AliPlayerKit setLocaleProvider:self.jaProvider];

覆盖已有翻译

仅需覆盖部分翻译时,Provider 只返回需要修改的 key,其余返回 nil 由 SDK 处理:

- (nullable NSString *)localizedStringForKey:(NSString *)key {
    // 仅覆盖"加载中"提示文案
    if ([key isEqualToString:LocaleKeyPlayStateLoading]) {
        return @"精彩即将呈现...";
    }
    return nil; // 其他 key 使用 SDK 内置翻译
}

移除自定义 Provider

// 移除 Provider,恢复使用 SDK 内置翻译
[AliPlayerKit setLocaleProvider:nil];

设计说明

字符串解析链(Resolution Chain)

LocaleManager 内部按以下优先级查找翻译:

优先级

来源

说明

1(最高)

Custom Provider

实现 LocaleProvider 协议的对象,通过 respondsToSelector: 检查后调用

2

activeBundle

当前激活的语言 Bundle(Manual 模式为手动指定语言,System 模式为系统语言)

3

sdkBundle fallback

当 activeBundle 与 sdkBundle 不同时,回退到 SDK Bundle 查询

4(最低)

Key fallback

直接返回 key 本身

线程安全

LocaleManager 内部使用串行队列(dispatch_queue_t)保护所有状态读写:

操作

线程安全机制

属性读取(currentLanguageCodelocaleMode

dispatch_sync 串行队列

语言切换方法(setLanguageCode: 等)

dispatch_sync 串行队列

通知发送

dispatch_async(dispatch_get_main_queue(), ...) 始终在主线程

Provider 持有

弱引用(weak

通知机制

通知名

触发时机

userInfo

LocaleDidChangeNotification

语言模式或语言代码变化时

LocaleLanguageCodeKey → 新语言代码

触发场景:

  • 调用 setLanguageCode: 切换手动语言

  • 调用 resetLocaleToSystemLanguage 恢复系统跟随

  • 调用 setLocaleProvider: 注入/移除 Provider

API 速查

AliPlayerKit 类方法

方法

说明

+setLanguageCode:

手动指定语言代码(如 @"en"@"zh-Hans"),localeMode 切换为 LocaleModeManual

+resetLocaleToSystemLanguage

恢复跟随系统语言,localeMode 切换为 LocaleModeSystem

+setLocaleProvider:

注入/移除自定义翻译 Provider(弱引用持有),传 nil 移除

+currentLanguageCode

获取当前生效的语言代码

LocaleManager实例方法

方法/属性

说明

+sharedManager

获取单例实例

currentLanguageCode

当前语言代码(readonly

localeMode

当前语言模式(readonlyLocaleModeSystem / LocaleModeManual

localeProvider

当前注入的 Provider(readonly,弱引用)

-setLanguageCode:

设置手动语言代码

-setLocaleProvider:

注入自定义 Provider

-resetToSystemLanguage

重置为跟随系统

-localizedStringForKey:

按解析链查询本地化字符串

LocaleProvider 协议

方法

必选

说明

-localizedStringForKey:

@optional

为指定 key 返回翻译,返回 nil 表示降级到 SDK 内置翻译

SDK内部使用的宏

用法

说明

LocalizedString(key)

LocalizedString(LocaleKeyPlayStateLoading)

获取本地化字符串

LocalizedFormat(key, ...)

LocalizedFormat(LocaleKeyBottomBarTimeFormat, min, sec, totalMin, totalSec)

获取格式化本地化字符串

通知常量

常量

类型

说明

LocaleDidChangeNotification

NSNotificationName

语言变更通知名

LocaleLanguageCodeKey

NSString *

通知 userInfo 中的新语言代码 Key

相关文件

文件

说明

PlayerKit/Source/Locale/LocaleManager.h

本地化管理器(单例)

PlayerKit/Source/Locale/LocaleProvider.h

自定义翻译 Provider 协议

PlayerKit/Source/Locale/LocaleKeys.h

所有本地化 Key 常量定义

PlayerKit/Source/Locale/LocaleMacros.h

SDK 内部使用的便捷宏

PlayerKit/Source/Locale/Localized.h

聚合头文件

PlayerKit/Source/AliPlayerKit.h

全局 API 入口(Locale 相关类方法)

PlayerKit.bundle/zh-Hans.lproj/Localizable.strings

简体中文翻译文件

PlayerKit.bundle/en.lproj/Localizable.strings

英文翻译文件

完整API请参见API参考

最佳实践

选择合适的方案

场景

推荐方案

说明

仅需中英文

无需任何操作

内置中英文,自动跟随系统语言

新增整套语言

LocaleProvider 全量翻译

实现协议,返回所有 key 的翻译

覆盖部分文案

LocaleProvider 部分翻译

仅处理需要覆盖的 key,其余返回 nil

强制指定语言

setLanguageCode:

不跟随系统,由应用自行控制

运行时动态切换

setLanguageCode: + 通知

切换后通过通知刷新自定义 UI

注意事项

事项

说明

Provider 生命周期

Provider 以弱引用持有,调用方需自行保持 Provider 实例不被释放

全量翻译

新增语言时建议翻译所有 LocaleKeys.h 中的 key,避免混合语言显示

语言代码规范

使用 Apple 标准 lproj 命名(如 zh-Hansenja

通知线程

LocaleDidChangeNotification 始终在主线程发送,可安全更新 UI

插槽自动刷新

内置插槽监听语言变更通知并自动刷新文案,自定义插槽需自行监听

示例参考

PlayerKitUsages/UsageLocaleSystem 模块提供了完整的本地化系统使用示例,包含语言切换、自定义 Provider 注入和变更通知监听。