622 changed files with 39193 additions and 8881 deletions
@ -1,3 +1,87 @@ |
|||
## 0.0.2 |
|||
|
|||
### iOS 端补全 / 与 Android 对齐(参考 `JIELI-IOS-Release`) |
|||
|
|||
#### 框架 |
|||
- 拷贝 `JIELI-IOS-Release/Libs/` 下全部 `.xcframework` + sample 项目里的 `JLAudioUnitKit.xcframework`(OPUS 编解码所需)到 `ios/Frameworks/`,通过 `vendored_frameworks` 引入。 |
|||
- `pubspec.yaml` 新增 `ios` 平台条目;`ios/device_jieli.podspec` 配置完成。 |
|||
|
|||
#### 与 Android 同名 / 同形态的核心通路(按 user 要求全量对齐) |
|||
|
|||
| 通路 | Android | iOS | |
|||
|---|---|---| |
|||
| 设备连接 | `ConnectFeature` → `JL_BluetoothManager.connect` + `setUseDeviceAuth(true)` | `ConnectFeature` → `JL_BLEMultiple.connectEntity` + `authEnable=true`;paired 后**自动调 `cmdTargetFeatureResult`** + `cmdGetSystemInfo(.COMMON)` 把 model 拉满,再外抛 `rcspInit` | |
|||
| 电量推送 | `OnRcspEventListener.onBatteryChange` → `battery` 事件 | `DeviceInfoEventForwarder` 订阅 `kJL_MANAGER_HEADSET_ADV` / `kJL_MANAGER_SYSTEM_INFO`,合成 `battery` 事件(带 `level/left/right/case` 字段,去重) | |
|||
| 通话状态 | `onPhoneCallStatusChange` → `phoneCallStatus` | `DeviceInfoEventForwarder` 订阅 `kJL_MANAGER_CALL_STATUS` | |
|||
| 通话翻译 mode=3 | `CallTranslationModeHandler` (uplink/downlink × OPUS 编解码) | `CallTranslationModeHandler` 完整复刻:`OpusStreamDecoder(channels=1, dataSize=40)` 分流 escoUp/escoDown,下行 PCM `OpusStreamEncoder` 编码后 `trWriteAudio(.escoUp/.escoDown)` | |
|||
| 通话翻译 mode=6(立体声)| `StereoCallTranslationModeHandler` + `PcmKit.splitStereo16` | `StereoCallTranslationModeHandler` 完整复刻:`OpusStreamDecoder(channels=2, dataSize=80)` → `PcmKit.splitStereo16` → uplink/downlink 两路 | |
|||
| MODE_CALL_TRANSLATION + OPUS 自动升级到 stereo | ✅ | ✅(`bypassStereoUpgrade=true` 可禁用,行为与 Android 一致) | |
|||
| AI 助理 | `JieliAssistantPort` (MODE_RECORD + STRATEGY_DEVICE_ALWAYS_RECORDING + OPUS) | `AssistantBridge` 复刻:通过 `TranslationSession.acquire` 拿独占所有权,`trStartTranslateMode(.onlyRecord, OPUS, ch=1)` + `recordtype=.byDevice`,`OpusStreamDecoder(channels=1, dataSize=40)` 解出 16k mono PCM → `assistantAudio` | |
|||
| 设备录音 | `JieliDeviceRecordPort` (mode=6 stereo + DEVICE_ALWAYS_RECORDING) | `DeviceRecordFeature` 复刻:`trStartTranslateMode(.callTranslateStereo, OPUS, ch=2)` + `recordtype=.byDevice`,`OpusStreamDecoder(channels=2, dataSize=80)` 解出 stereo PCM → `deviceRecordAudio` | |
|||
| OTA | 自实现 cmd-level 状态机 | 直接走 `JL_BLEMultiple.otaFunc(...)` 高层 API,结果回调映射到 `otaState` / `otaError` | |
|||
|
|||
#### TranslationSession 互斥模型 |
|||
iOS SDK 一台设备只有一个 `JLTranslationManager`,与 Android 同样要求"翻译 / 助理 / 设备录音"三选一互斥。新增 [TranslationSession](ios/Classes/core/TranslationSession.swift): |
|||
- 内部持有 `JLTranslationManager` 实例,自身作为 `JLTranslationManagerDelegate` |
|||
- 通过 `acquire(owner:)` / `release(owner:)` 协调当前会话所有者 |
|||
- 所有 SDK 回调(`onReceiveAudioData` / `onModeChange` / `onError` / `onSendAudioQueueOver` / `isOnCalling`)fan-out 到当前 owner |
|||
|
|||
#### 文件清单(`ios/Classes/`) |
|||
``` |
|||
JielihomePlugin.swift # Flutter 入口 |
|||
MethodRouter.swift # MethodChannel 路由 |
|||
EventDispatcher.swift # EventChannel 总线 |
|||
JieliHomeServer.swift # 单例 + per-device session |
|||
|
|||
core/TranslationSession.swift # 设备级翻译会话所有者协调 |
|||
audio/OpusStreamCodec.swift # JLOpusDecoder/Encoder 包装 |
|||
audio/PcmKit.swift # 16-bit stereo split / interleave |
|||
|
|||
event/BluetoothEventForwarder.swift # BLE 状态 / 连接通知 |
|||
event/CustomEventForwarder.swift # 厂商扩展指令 |
|||
event/DeviceInfoEventForwarder.swift # 电量 / 通话 / 系统信息 |
|||
|
|||
feature/ScanFeature.swift |
|||
feature/ConnectFeature.swift |
|||
feature/DeviceInfoFeature.swift |
|||
feature/CustomCmdFeature.swift |
|||
feature/OtaFeature.swift |
|||
feature/TranslationFeature.swift # 6-mode dispatcher |
|||
feature/translation/TranslationConstants.swift |
|||
feature/translation/TranslationModeHandler.swift |
|||
feature/translation/mode/RecordModeHandler.swift (mode=1 + RecordingTranslation mode=2) |
|||
feature/translation/mode/CallTranslationModeHandler.swift (mode=3) |
|||
feature/translation/mode/StereoCallTranslationModeHandler.swift (mode=6) |
|||
feature/translation/mode/AudioAndFaceModeHandlers.swift (mode=4 + mode=5) |
|||
feature/AssistantBridge.swift |
|||
feature/DeviceRecordFeature.swift |
|||
feature/SpeechFeature.swift # 状态机骨架(详见下方) |
|||
``` |
|||
|
|||
### 与 Android 实际差异 |
|||
|
|||
| 项 | Android | iOS | 影响 | |
|||
|---|---|---|---| |
|||
| `address` 含义 | BLE MAC | CoreBluetooth identifier (UUID) | iOS 系统对 BLE MAC 永久匿名;上层若用 address 做主键需要做厂商适配 | |
|||
| 录音策略 | 三选一:CUSTOM/ALWAYS/AUTO | 二选一:`.byPhone`(=CUSTOM) / `.byDevice`(=ALWAYS) | iOS SDK 不暴露 AUTO(VAD 自动启停),调用 `strategy="auto"` 时回退到 default | |
|||
| `versionCode` 字段 | SDK 有 numeric versionCode | SDK 只有 versionFirmware(字符串) | `deviceSnapshot` 里 versionCode 为 null | |
|||
| `sendCustomCmd` opCode | SDK 有专门字段 | iOS `JL_CustomManager.cmdCustomData:` 无 opCode 字段 | iOS 实现把 Dart 传入的 opCode 拼到 payload 头部(业务双方约定) | |
|||
| `OTA` 状态机 | 插件自实现 cmd 级状态机 | 直接走 SDK 高层 API | Dart `otaStart` 的 `blockSize` / `fileFlag` 参数 iOS 端忽略 | |
|||
| `speechStart/Stop`(cmd=4/5 通路) | 完整实现 | 仅状态机外抛 `speechStart/End`,**不拉真实音频** | iOS SDK 4.2 beta 没把 cmd=4/5 通路暴露成公开 Swift API;耳机硬件唤醒的上行帧通过翻译通路接管 | |
|||
|
|||
### 真机验证状态 |
|||
|
|||
| 子系统 | 单元自测 | 真机验证 | |
|||
|---|---|---| |
|||
| 扫描 / 连接 / 断开 | ✅ 编译通过 | ⬜ | |
|||
| `battery` / `phoneCallStatus` 推送 | ✅ | ⬜ | |
|||
| `deviceSnapshot` / `queryTargetInfo` / `sendCustomCmd` | ✅ | ⬜ | |
|||
| OTA | ✅ | ⬜ | |
|||
| 通话翻译 mode=3 + OPUS 上下行 | ✅ | ⬜ | |
|||
| 通话翻译 mode=6 立体声 | ✅ | ⬜ | |
|||
| AI 助理 (MODE_RECORD + byDevice + OPUS) | ✅ | ⬜ | |
|||
| 设备录音 (mode=6 + stereo + byDevice + OPUS) | ✅ | ⬜ | |
|||
|
|||
## 0.0.1 |
|||
|
|||
* TODO: Describe initial release. |
|||
|
|||
@ -1,15 +1,42 @@ |
|||
# jielihome |
|||
# device_jieli |
|||
|
|||
JieLi Home SDK Flutter plugin |
|||
Flutter plugin around the JieLi (杰理) RCSP Bluetooth SDK. Provides a vendor-agnostic |
|||
MethodChannel / EventChannel surface (`device_jieli/method`, `device_jieli/event`) |
|||
so Dart-side code can scan / connect / query / OTA / translate against JieLi earpieces |
|||
on both Android and iOS. |
|||
|
|||
## Getting Started |
|||
## Platforms |
|||
|
|||
This project is a starting point for a Flutter |
|||
[plug-in package](https://flutter.dev/to/develop-plugins), |
|||
a specialized package that includes platform-specific implementation code for |
|||
Android and/or iOS. |
|||
| Platform | Native SDK | Status | |
|||
|---|---|---| |
|||
| Android | `android/libs/jl_bluetooth_rcsp_*.aar` etc. | Functional (used in production demo) | |
|||
| iOS | `ios/Frameworks/JL_BLEKit.xcframework` etc. (from `JIELI-IOS-Release/Libs`) | **Compiles,真机验证未完成** — see [CHANGELOG.md](CHANGELOG.md) for the per-feature status matrix. | |
|||
|
|||
For help getting started with Flutter development, view the |
|||
[online documentation](https://docs.flutter.dev), which offers tutorials, |
|||
samples, guidance on mobile development, and a full API reference. |
|||
## iOS setup |
|||
|
|||
The plugin ships every required `.xcframework` under `ios/Frameworks/`. When the upstream |
|||
SDK in `JIELI-IOS-Release/Libs/` updates, mirror the new `.xcframework` directories on |
|||
top of `ios/Frameworks/` (overwrite is safe) and `pod install` again in the host app. |
|||
|
|||
Minimum target: iOS 12. |
|||
|
|||
The host app must declare in `Info.plist`: |
|||
|
|||
```xml |
|||
<key>NSBluetoothAlwaysUsageDescription</key> |
|||
<string>用于连接杰理蓝牙耳机</string> |
|||
<key>NSBluetoothPeripheralUsageDescription</key> |
|||
<string>用于连接杰理蓝牙耳机</string> |
|||
<key>NSMicrophoneUsageDescription</key> |
|||
<string>用于翻译 / 语音助手录音</string> |
|||
``` |
|||
|
|||
## Channel surface |
|||
|
|||
Dart API lives in [`lib/device_jieli.dart`](lib/device_jieli.dart). Native code on either |
|||
platform implements the same set of method calls and emits the same event payload schema — |
|||
the iOS implementation lives in [`ios/Classes/`](ios/Classes/), the Android |
|||
implementation in [`android/src/main/kotlin/com/jielihome/jielihome/`](android/src/main/kotlin/com/jielihome/jielihome/). |
|||
|
|||
For background on the RCSP commands and translation pipeline see |
|||
[`JIELI_SDK_COMMANDS.md`](JIELI_SDK_COMMANDS.md). |
|||
|
|||
@ -0,0 +1,44 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>AvailableLibraries</key> |
|||
<array> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLAudioUnitKit.framework/JLAudioUnitKit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>ios-arm64_x86_64-simulator</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLAudioUnitKit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>x86_64</string> |
|||
<string>arm64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>ios</string> |
|||
<key>SupportedPlatformVariant</key> |
|||
<string>simulator</string> |
|||
</dict> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLAudioUnitKit.framework/JLAudioUnitKit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>ios-arm64</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLAudioUnitKit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>arm64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>ios</string> |
|||
</dict> |
|||
</array> |
|||
<key>CFBundlePackageType</key> |
|||
<string>XFWK</string> |
|||
<key>XCFrameworkFormatVersion</key> |
|||
<string>1.0</string> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1,26 @@ |
|||
//
|
|||
// JLAudioUnitKit.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLAudioUnitKit.
|
|||
FOUNDATION_EXPORT double JLAudioUnitKitVersionNumber; |
|||
|
|||
//! Project version string for JLAudioUnitKit.
|
|||
FOUNDATION_EXPORT const unsigned char JLAudioUnitKitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLAudioUnitKit/PublicHeader.h>
|
|||
|
|||
#import <JLAudioUnitKit/JLSpeexDecoder.h> |
|||
#import <JLAudioUnitKit/JLOpusDecoder.h> |
|||
#import <JLAudioUnitKit/JLOpusEncoder.h> |
|||
#import <JLAudioUnitKit/JLOpusFormat.h> |
|||
#import <JLAudioUnitKit/JLOpusEncodeConfig.h> |
|||
#import <JLAudioUnitKit/JLPcmToWtg.h> |
|||
#import <JLAudioUnitKit/JLPcmToWav.h> |
|||
#import <JLAudioUnitKit/JLAudioUnitPlayer.h> |
|||
#import <JLAudioUnitKit/JLOpusToOgg.h> |
|||
@ -0,0 +1,58 @@ |
|||
//
|
|||
// JLAudioUnitPlayer.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/4/16.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <AudioToolbox/AudioToolbox.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
typedef NS_ENUM(NSInteger, JLAudioUnitPlayerType) { |
|||
JLAudioUnitPlayerTypeFile, // 支持 MP3/WAV/AAC 等文件格式(AVAudioPlayer)
|
|||
JLAudioUnitPlayerTypePCM // 支持 PCM 流式播放(Audio Queue)
|
|||
}; |
|||
|
|||
@class JLAudioUnitPlayer; |
|||
|
|||
@protocol JLAudioPlayerDelegate <NSObject> |
|||
@optional |
|||
// 播放进度更新(秒)
|
|||
- (void)audioPlayer:(JLAudioUnitPlayer *)player didUpdateProgress:(NSTimeInterval)currentTime duration:(NSTimeInterval)duration; |
|||
// 播放完成
|
|||
- (void)audioPlayerDidFinishPlaying:(JLAudioUnitPlayer *)player; |
|||
// 播放错误
|
|||
- (void)audioPlayer:(JLAudioUnitPlayer *)player didFailWithError:(NSError *)error; |
|||
@end |
|||
|
|||
@interface JLAudioUnitPlayer : NSObject |
|||
|
|||
@property (nonatomic, weak) id<JLAudioPlayerDelegate> delegate; |
|||
@property (nonatomic, readonly) NSTimeInterval duration; // 总时长(文件模式下有效)
|
|||
@property (nonatomic, readonly) NSTimeInterval currentTime; |
|||
@property (nonatomic, readonly) BOOL isPlaying; |
|||
|
|||
#pragma mark - 初始化方法 |
|||
|
|||
/// 文件播放初始化(MP3/WAV/AAC)
|
|||
- (instancetype)initWithAudioFile:(NSString *)filePath; |
|||
|
|||
/// PCM 流播放初始化(需指定格式)
|
|||
- (instancetype)initWithPCMFormat:(AudioStreamBasicDescription)format; |
|||
|
|||
#pragma mark - 播放控制 |
|||
- (void)play; |
|||
- (void)pause; |
|||
- (void)stop; |
|||
- (void)seekToTime:(NSTimeInterval)time; // 仅文件模式有效
|
|||
|
|||
#pragma mark - PCM 流式输入(仅 PCM 模式有效) |
|||
- (void)appendPCMData:(NSData *)pcmData; |
|||
- (void)endPCMStream; // 结束 PCM 流输入
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,66 @@ |
|||
//
|
|||
// JLOpusDecoder.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
// Copyright © 2024 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLAudioUnitKit/JLOpusFormat.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLOpusDecoder; |
|||
|
|||
/// Opus 解码代理
|
|||
@protocol JLOpusDecoderDelegate <NSObject> |
|||
|
|||
/// Opus 数据解码
|
|||
/// - Parameters:
|
|||
/// - decoder: 解码器
|
|||
/// - data: pcm 数据
|
|||
/// - error: 错误信息
|
|||
-(void)opusDecoder:(JLOpusDecoder *)decoder Data:(NSData* _Nullable)data error:(NSError* _Nullable)error; |
|||
|
|||
@end |
|||
|
|||
typedef void(^JLOpusDecoderConvertBlock)(NSString *_Nullable pcmPath,NSError *_Nullable error); |
|||
|
|||
/// Opus 解码
|
|||
@interface JLOpusDecoder : NSObject |
|||
|
|||
/// 数据格式参数
|
|||
@property (nonatomic, strong) JLOpusFormat *opusFormat; |
|||
|
|||
/// 代理委托
|
|||
@property(nonatomic, weak) id<JLOpusDecoderDelegate> delegate; |
|||
|
|||
- (instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - format: 解码格式
|
|||
/// - delegate: 代理
|
|||
- (instancetype)initDecoder:(JLOpusFormat *)format delegate:(id<JLOpusDecoderDelegate>)delegate; |
|||
|
|||
/// 重置解码格式
|
|||
/// - Parameter format: 解码格式
|
|||
-(void)resetOpusFramet:(JLOpusFormat *)format; |
|||
|
|||
/// 输入 Opus 数据
|
|||
/// - Parameter data: Opus 数据
|
|||
-(void)opusDecoderInputData:(NSData *)data; |
|||
|
|||
/// 解码文件
|
|||
/// - Parameters:
|
|||
/// - input: opus 文件
|
|||
/// - outPut: 输出路径
|
|||
/// - result: 结果回调
|
|||
-(void)opusDecodeFile:(NSString *)input outPut:(NSString *_Nullable)outPut Resoult:(JLOpusDecoderConvertBlock _Nullable)result; |
|||
|
|||
/// 释放
|
|||
-(void)opusOnRelease; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,83 @@ |
|||
//
|
|||
// JLOpusEncodeConfig.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/8/27.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
typedef NS_ENUM(NSInteger, JLOpusEncoderBandwidth) { |
|||
///(4kHz bandpass)
|
|||
JLOpusEncoderBandwidthNarrowband = 1101, // 对应 OPUS_BANDWIDTH_NARROWBAND
|
|||
/// (6kHz bandpass)
|
|||
JLOpusEncoderBandwidthMediumband = 1102, // 对应 OPUS_BANDWIDTH_MEDIUMBAND
|
|||
/// (8kHz bandpass)
|
|||
JLOpusEncoderBandwidthWideband = 1103, // 对应 OPUS_BANDWIDTH_WIDEBAND
|
|||
/// (12kHz bandpass)
|
|||
JLOpusEncoderBandwidthSuperwideband = 1104,// 对应 OPUS_BANDWIDTH_SUPERWIDEBAND
|
|||
/// (20kHz bandpass)
|
|||
JLOpusEncoderBandwidthFullband = 1105 // 对应 OPUS_BANDWIDTH_FULLBAND
|
|||
}; |
|||
|
|||
@interface JLOpusEncodeConfig : NSObject |
|||
|
|||
/// 采样率
|
|||
@property (nonatomic, assign) int sampleRate; |
|||
|
|||
/// 单/双声道
|
|||
@property (nonatomic, assign) int channels; |
|||
|
|||
/// 帧长度 20ms 默认值
|
|||
@property (nonatomic, assign) int frameDuration; |
|||
|
|||
/// 帧长度
|
|||
@property (nonatomic, assign) int frameSize; |
|||
|
|||
/// BitRate
|
|||
@property (nonatomic, assign) int bitRate; |
|||
|
|||
/// 可变比特率开关,默认 NO(使用 CBR)
|
|||
@property (nonatomic, assign) BOOL useVBR; |
|||
|
|||
/// VBR 限制模式,默认 NO
|
|||
@property (nonatomic, assign) BOOL constrainedVBR; |
|||
|
|||
/// 编码复杂度 0~10,默认 5
|
|||
@property (nonatomic, assign) int complexity; |
|||
|
|||
/// 强制输出声道数 -1: 自适应, 1: 单声道, 2: 双声道, 默认 -1
|
|||
@property (nonatomic, assign) int forceChannels; |
|||
|
|||
/// 是否启用 DTX(静音段不发送数据),默认 NO
|
|||
@property (nonatomic, assign) BOOL useDTX; |
|||
|
|||
/// 网络丢包百分比,默认 0
|
|||
@property (nonatomic, assign) int packetLossPercent; |
|||
|
|||
/// 最大带宽限制(OPUS_BANDWIDTH_*),默认 FULLBAND
|
|||
@property (nonatomic, assign) int bandwidth; |
|||
|
|||
/// PCM 输入有效位深,默认 16
|
|||
@property (nonatomic, assign) int lsbDepth; |
|||
|
|||
/// 专家模式下帧时长(ms),默认与 frameDuration 一致
|
|||
@property (nonatomic, assign) int expertFrameDuration; |
|||
|
|||
/// 是否启用数据头
|
|||
/// 默认是启用的
|
|||
@property (nonatomic, assign) BOOL hasDataHeader; |
|||
|
|||
/// 创建默认编码配置
|
|||
+ (instancetype)defaultConfig; |
|||
|
|||
/// 获取默认配置
|
|||
/// 杰理的无头配置
|
|||
+ (instancetype)defaultJL; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,69 @@ |
|||
//
|
|||
// JLOpusEncoder.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
// Copyright © 2024 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLAudioUnitKit/JLOpusEncodeConfig.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLOpusEncoder; |
|||
|
|||
/// Opus 编码代理
|
|||
@protocol JLOpusEncoderDelegate <NSObject> |
|||
|
|||
/// PCM 数据编码
|
|||
/// - Parameters:
|
|||
/// - encoder: 解码器
|
|||
/// - data: opus 数据
|
|||
/// - error: 错误信息
|
|||
-(void)opusEncoder:(JLOpusEncoder *)encoder Data:(NSData* _Nullable)data error:(NSError* _Nullable)error; |
|||
|
|||
@end |
|||
|
|||
typedef void(^JLOpusEncoderConvertBlock)(NSString *_Nullable pcmPath,NSError *_Nullable error); |
|||
|
|||
/// Opus 编码
|
|||
@interface JLOpusEncoder : NSObject |
|||
|
|||
/// 音频格式
|
|||
@property (nonatomic, strong) JLOpusEncodeConfig *opusFormat; |
|||
|
|||
/// 代理
|
|||
@property (nonatomic, weak) id<JLOpusEncoderDelegate> delegate; |
|||
|
|||
-(instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - config: 音频格式
|
|||
/// - delegate: 代理
|
|||
-(instancetype)initFormat:(JLOpusEncodeConfig *)format delegate:(id<JLOpusEncoderDelegate>)delegate; |
|||
|
|||
/// PCM 数据
|
|||
/// - Parameter data: PCM 数据
|
|||
-(void)opusEncodeData:(NSData *)data; |
|||
|
|||
/// PCM 文件转换成 Opus 文件(推荐新接口,流式读取,避免一次性加载内存)
|
|||
/// - Parameters:
|
|||
/// - pcmPath: PCM 文件存放路径
|
|||
/// - output: 文件输出路径(可空,默认 ~/Documents/pcmToOpus.opus)
|
|||
/// - result: 结果回调,回传输出路径或错误
|
|||
-(void)opusEncodeFile:(NSString *)pcmPath output:(NSString *_Nullable)output result:(JLOpusEncoderConvertBlock _Nullable)result; |
|||
|
|||
/// 兼容旧接口(已废弃:命名拼写问题,且旧实现一次性读入文件)
|
|||
/// - Parameters:
|
|||
/// - pcmPath: PCM 文件存放路径
|
|||
/// - outPut: 文件输出路径
|
|||
/// - result: 结果回调
|
|||
-(void)opusEncodeFile:(NSString *)pcmPath outPut:(NSString *_Nullable)outPut Resoult:(JLOpusEncoderConvertBlock _Nullable)result __attribute__((deprecated("Use opusEncodeFile:output:result: instead."))); |
|||
|
|||
/// 释放
|
|||
-(void)opusOnRelease; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,59 @@ |
|||
//
|
|||
// JLOpusOptions.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
// Copyright © 2024 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
#define OPUS_JL_MAX_FRAME_SIZE 48000 * 2 |
|||
#define OPUS_JL_MAX_PACKET_SIZE 1500 |
|||
|
|||
|
|||
@interface JLOpusFormat : NSObject |
|||
|
|||
/// 采样率
|
|||
@property (nonatomic, assign) int sampleRate; |
|||
|
|||
/// 单/双声道
|
|||
@property (nonatomic, assign) int channels; |
|||
|
|||
/// 帧长度 20ms 默认值
|
|||
@property (nonatomic, assign) int frameDuration; |
|||
|
|||
/// BitRate
|
|||
@property (nonatomic, assign) int bitRate; |
|||
|
|||
/// 数据帧大小
|
|||
@property (nonatomic, assign, readonly) int frameSize; |
|||
|
|||
/// 数据大小
|
|||
@property (nonatomic, assign) int dataSize; |
|||
|
|||
/// 是否包含数据头部
|
|||
@property (nonatomic, assign) BOOL hasDataHeader; |
|||
|
|||
/// 是否开启slik语音优化
|
|||
@property (nonatomic, assign) BOOL usVoipSlik; |
|||
|
|||
|
|||
-(instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 默认配置
|
|||
/// sampleRate: 16000
|
|||
/// channels: 1
|
|||
/// frameDuration: 20
|
|||
/// dataSize: 40
|
|||
/// frameSize: 320
|
|||
/// hasDataHeader: YES
|
|||
/// bitRate: 16000
|
|||
/// usVoipSlik: false
|
|||
+(JLOpusFormat*)defaultFormats; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,67 @@ |
|||
//
|
|||
// JLOpusToOgg.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/5/16.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
typedef void(^JLOpusToOggConvertBlock)(NSData *_Nullable oggData, BOOL isLast, NSError *_Nullable error); |
|||
|
|||
/// 将Opus数据转换为Ogg数据
|
|||
@interface JLOpusToOgg : NSObject |
|||
|
|||
/// 转码内容的回调
|
|||
@property(nonatomic,strong)JLOpusToOggConvertBlock _Nullable convertBlock; |
|||
|
|||
/// 帧长
|
|||
/// - Parameter frameLen: 帧长
|
|||
/// 默认值 40
|
|||
- (instancetype)initWithFrameLength:(uint32_t)frameLen; |
|||
|
|||
/// 开始流
|
|||
-(void)startStream; |
|||
|
|||
/// 添加Opus数据
|
|||
/// - Parameter opusData: 符合杰理的无头裸 opus 数据
|
|||
- (void)appendOpusData:(NSData *)opusData; |
|||
|
|||
/// 关闭流
|
|||
- (void)closeStream; |
|||
|
|||
|
|||
/// 将Opus数据转换为Ogg数据
|
|||
/// opus 必须为 16000
|
|||
/// opus 必须是 单声道
|
|||
/// - Parameters:
|
|||
/// - opusData: 符合杰理的无头裸 opus 数据
|
|||
/// - frameLen: 帧长 公版默认帧长是 40
|
|||
/// - duration: 转换后的时长
|
|||
/// - error: 错误
|
|||
+ (NSData *_Nullable)convertOpusDataToOgg:(NSData *)opusData |
|||
frameLen:(uint32_t)frameLen |
|||
duration:(double *)duration |
|||
error:(NSError *__autoreleasing _Nullable *)error ; |
|||
|
|||
/// 将Opus文件转换为Ogg文件
|
|||
/// 符合杰理的无头裸 opus 文件
|
|||
/// opus 必须为 16000
|
|||
/// opus 必须是 单声道
|
|||
/// - Parameters:
|
|||
/// - opusFilePath: opus文件路径
|
|||
/// - oggFilePath: ogg文件路径
|
|||
/// - frameLen: 帧长 公版默认帧长是 40
|
|||
/// - duration: 转换后的时长
|
|||
+(void)convertOpusFileToOgg:(NSString *)opusFilePath |
|||
oggFilePath:(NSString *)oggFilePath |
|||
frameLen:(uint32_t)frameLen |
|||
duration:(double *)duration; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,55 @@ |
|||
//
|
|||
// JLPcmToWav.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/4/15.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// PCM 转 WAV
|
|||
@interface JLPcmToWav : NSObject |
|||
|
|||
#pragma mark - 流式编码接口 |
|||
|
|||
/// 初始化流式编码器
|
|||
/// @param outputPath 输出文件路径
|
|||
/// @param sampleRate 采样率(如 16000)
|
|||
/// @param numChannels 声道数(1 或 2)
|
|||
/// @param bitsPerSample 位深(16)
|
|||
- (instancetype)initWithOutputPath:(NSString *)outputPath |
|||
sampleRate:(uint32_t)sampleRate |
|||
numChannels:(uint16_t)numChannels |
|||
bitsPerSample:(uint16_t)bitsPerSample; |
|||
|
|||
/// 追加 PCM 数据(需确保数据格式与初始化参数一致)
|
|||
/// @param pcmData PCM 数据块
|
|||
/// @param error 错误信息
|
|||
- (BOOL)appendPCMData:(NSData *)pcmData error:(NSError **)error; |
|||
|
|||
/// 完成编码并关闭文件(必须调用以更新 WAV 头)
|
|||
/// @param error 错误信息
|
|||
- (BOOL)finishWithError:(NSError **)error; |
|||
|
|||
#pragma mark - 一次性编码接口(便捷方法) |
|||
|
|||
/// 将 PCM 数据一次性转为 WAV 文件
|
|||
/// @param pcmData PCM 数据块
|
|||
/// @param outputPath 输出文件路径
|
|||
/// @param sampleRate 采样率(如 16000)
|
|||
/// @param numChannels 声道数(1 或 2)
|
|||
/// @param bitsPerSample 位深(16)
|
|||
/// @param error 错误信息
|
|||
+ (BOOL)convertPCMData:(NSData *)pcmData |
|||
toWAVFile:(NSString *)outputPath |
|||
sampleRate:(uint32_t)sampleRate |
|||
numChannels:(uint16_t)numChannels |
|||
bitsPerSample:(uint16_t)bitsPerSample |
|||
error:(NSError **)error; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,51 @@ |
|||
//
|
|||
// JLPcmToWtg.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/1/21.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
@interface JLPcm2WtgModel : NSObject <NSCopying> |
|||
|
|||
/// 音频文件
|
|||
@property (nonatomic, copy) NSString *pcmPath; |
|||
|
|||
/// 输出文件
|
|||
@property (nonatomic, copy) NSString *wtgPath; |
|||
|
|||
@end |
|||
|
|||
|
|||
/// JLPcmToWtgProtocol
|
|||
@protocol JLPcmToWtgDelegate <NSObject> |
|||
|
|||
/// 音频转码完成
|
|||
/// - Parameter model: 音频转码模型
|
|||
- (void)convertPcmToWtgDone:(JLPcm2WtgModel *)model; |
|||
|
|||
@end |
|||
|
|||
/// 音频转码
|
|||
/// PCM 转 WTG
|
|||
@interface JLPcmToWtg : NSObject |
|||
|
|||
- (instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 音频转码初始化
|
|||
/// - Parameter delegate: 音频转码代理
|
|||
- (instancetype)initWithDelegate:(id<JLPcmToWtgDelegate>)delegate; |
|||
|
|||
/// 音频转码
|
|||
/// 当前接口模型只限制 PCM 文件格式为:8k 16bit
|
|||
/// 输入的pcm文件(16bit,小端,8k采样率),wtg_filename:输出的wtg文件
|
|||
/// - Parameter model: 音频转码模型
|
|||
-(void)convertPcmToWtg:(JLPcm2WtgModel *)model; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,54 @@ |
|||
//
|
|||
// JLSpeexUnit.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLSpeexDecoder; |
|||
|
|||
@protocol JLSpeexDelegate <NSObject> |
|||
|
|||
/// Speex 数据解码
|
|||
/// - Parameters:
|
|||
/// - decoder: 解码器
|
|||
/// - data: PCM 数据
|
|||
/// - error: 错误信息
|
|||
- (void)speexDecoder:(JLSpeexDecoder *)decoder Data:(NSData* _Nullable)data error:(NSError* _Nullable)error; |
|||
|
|||
@end |
|||
|
|||
typedef void(^JLSpeexConvertBlock)(NSString *_Nullable pcmPath,NSError *_Nullable error); |
|||
|
|||
/// Speex 数据解码
|
|||
@interface JLSpeexDecoder : NSObject |
|||
|
|||
-(instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 初始化
|
|||
/// - Parameter delegate: 委托
|
|||
-(instancetype)initWithDelegate:(id<JLSpeexDelegate>)delegate; |
|||
|
|||
/// 委托
|
|||
@property (nonatomic, weak) id<JLSpeexDelegate> delegate; |
|||
|
|||
/// 输入 Speex 数据
|
|||
/// - Parameter data: Speex 数据
|
|||
-(void)speexInputData:(NSData*)data; |
|||
|
|||
/// 将 Speex 转换为 PCM
|
|||
/// - Parameters:
|
|||
/// - filePath: Speex 路径
|
|||
/// - opPath: 输出路径
|
|||
/// - result: 结果回调
|
|||
-(void)speexConvertToPcm:(NSString *)filePath outPutFilePath:(NSString * _Nullable)opPath Result:(JLSpeexConvertBlock)result; |
|||
|
|||
/// 释放对象
|
|||
-(void)speexOnRelease; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
framework module JLAudioUnitKit { |
|||
umbrella header "JLAudioUnitKit.h" |
|||
export * |
|||
|
|||
module * { export * } |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
DESCRIPTION |
|||
----------- |
|||
This package includes the files needed to build the fixed point implementation |
|||
of the ITU-T G.729 Appendix IV. |
|||
|
|||
DIFFERENCES WITH G.729B |
|||
----------------------- |
|||
The ANSI-C source code simulating the bit-exact, fixed point simulation |
|||
software of enhanced VAD is integrated into the G.729B source code. |
|||
The modification to the G.729B source code updated files of coder.c, |
|||
cod_ld8k.c, bits.c, dec_sid.c, dtx.c, qsidgain.c, qsidlsf.c, tab_dtx.c, |
|||
tab_dtx.h, ld8k.h, deleted vad.c/h and integrated the enhanced VAD functions |
|||
into the G.729B project. The modification also replaced the original basic |
|||
operators used in the original G.729B source code by the basic operators of |
|||
ITU-T Software Tool Library STL2005. |
|||
|
|||
COMPILATION |
|||
----------- |
|||
For UNIX systems the following makefiles are provided |
|||
|
|||
coder.mak |
|||
decoder.mak |
|||
|
|||
Edit the makefiles coder.mak and decoder.mak to set the proper options |
|||
for your system. |
|||
The command to compile and link all code on a UNIX system is |
|||
|
|||
make -f coder.mak |
|||
make -f decoder.mak |
|||
|
|||
For other platforms, the *.mak files can be used to work out the |
|||
compilation procedures. |
|||
|
|||
USAGE |
|||
----- |
|||
The command line instruction for the encoder is as follows: |
|||
coder inputfile bitstreamfile dtx_option mode x |
|||
where: |
|||
inputfile : 8 kHz sampled data file containing 16 bit linear PCM signal |
|||
bitstreamfile: binary file containing bitstream |
|||
dtx_option : = 1 : DTX enabled 0 : DTX disabled |
|||
mode X : Run encoder with enhanced VAD in operating point X, |
|||
X=0 or 1 or 2 representing balanced or quality-preferred |
|||
or bandwidth saving operating point, respectively |
|||
|
|||
The command line for the decoder is as follows: |
|||
decoder bitstreamfile outputfile |
|||
where: |
|||
bitstreamfile: binary file containing bitstream |
|||
outputfile : 8 kHz sampled data file containing 16 bit linear PCM signal |
|||
|
|||
|
|||
@ -0,0 +1,26 @@ |
|||
//
|
|||
// JLAudioUnitKit.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLAudioUnitKit.
|
|||
FOUNDATION_EXPORT double JLAudioUnitKitVersionNumber; |
|||
|
|||
//! Project version string for JLAudioUnitKit.
|
|||
FOUNDATION_EXPORT const unsigned char JLAudioUnitKitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLAudioUnitKit/PublicHeader.h>
|
|||
|
|||
#import <JLAudioUnitKit/JLSpeexDecoder.h> |
|||
#import <JLAudioUnitKit/JLOpusDecoder.h> |
|||
#import <JLAudioUnitKit/JLOpusEncoder.h> |
|||
#import <JLAudioUnitKit/JLOpusFormat.h> |
|||
#import <JLAudioUnitKit/JLOpusEncodeConfig.h> |
|||
#import <JLAudioUnitKit/JLPcmToWtg.h> |
|||
#import <JLAudioUnitKit/JLPcmToWav.h> |
|||
#import <JLAudioUnitKit/JLAudioUnitPlayer.h> |
|||
#import <JLAudioUnitKit/JLOpusToOgg.h> |
|||
@ -0,0 +1,58 @@ |
|||
//
|
|||
// JLAudioUnitPlayer.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/4/16.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <AudioToolbox/AudioToolbox.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
typedef NS_ENUM(NSInteger, JLAudioUnitPlayerType) { |
|||
JLAudioUnitPlayerTypeFile, // 支持 MP3/WAV/AAC 等文件格式(AVAudioPlayer)
|
|||
JLAudioUnitPlayerTypePCM // 支持 PCM 流式播放(Audio Queue)
|
|||
}; |
|||
|
|||
@class JLAudioUnitPlayer; |
|||
|
|||
@protocol JLAudioPlayerDelegate <NSObject> |
|||
@optional |
|||
// 播放进度更新(秒)
|
|||
- (void)audioPlayer:(JLAudioUnitPlayer *)player didUpdateProgress:(NSTimeInterval)currentTime duration:(NSTimeInterval)duration; |
|||
// 播放完成
|
|||
- (void)audioPlayerDidFinishPlaying:(JLAudioUnitPlayer *)player; |
|||
// 播放错误
|
|||
- (void)audioPlayer:(JLAudioUnitPlayer *)player didFailWithError:(NSError *)error; |
|||
@end |
|||
|
|||
@interface JLAudioUnitPlayer : NSObject |
|||
|
|||
@property (nonatomic, weak) id<JLAudioPlayerDelegate> delegate; |
|||
@property (nonatomic, readonly) NSTimeInterval duration; // 总时长(文件模式下有效)
|
|||
@property (nonatomic, readonly) NSTimeInterval currentTime; |
|||
@property (nonatomic, readonly) BOOL isPlaying; |
|||
|
|||
#pragma mark - 初始化方法 |
|||
|
|||
/// 文件播放初始化(MP3/WAV/AAC)
|
|||
- (instancetype)initWithAudioFile:(NSString *)filePath; |
|||
|
|||
/// PCM 流播放初始化(需指定格式)
|
|||
- (instancetype)initWithPCMFormat:(AudioStreamBasicDescription)format; |
|||
|
|||
#pragma mark - 播放控制 |
|||
- (void)play; |
|||
- (void)pause; |
|||
- (void)stop; |
|||
- (void)seekToTime:(NSTimeInterval)time; // 仅文件模式有效
|
|||
|
|||
#pragma mark - PCM 流式输入(仅 PCM 模式有效) |
|||
- (void)appendPCMData:(NSData *)pcmData; |
|||
- (void)endPCMStream; // 结束 PCM 流输入
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,66 @@ |
|||
//
|
|||
// JLOpusDecoder.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
// Copyright © 2024 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLAudioUnitKit/JLOpusFormat.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLOpusDecoder; |
|||
|
|||
/// Opus 解码代理
|
|||
@protocol JLOpusDecoderDelegate <NSObject> |
|||
|
|||
/// Opus 数据解码
|
|||
/// - Parameters:
|
|||
/// - decoder: 解码器
|
|||
/// - data: pcm 数据
|
|||
/// - error: 错误信息
|
|||
-(void)opusDecoder:(JLOpusDecoder *)decoder Data:(NSData* _Nullable)data error:(NSError* _Nullable)error; |
|||
|
|||
@end |
|||
|
|||
typedef void(^JLOpusDecoderConvertBlock)(NSString *_Nullable pcmPath,NSError *_Nullable error); |
|||
|
|||
/// Opus 解码
|
|||
@interface JLOpusDecoder : NSObject |
|||
|
|||
/// 数据格式参数
|
|||
@property (nonatomic, strong) JLOpusFormat *opusFormat; |
|||
|
|||
/// 代理委托
|
|||
@property(nonatomic, weak) id<JLOpusDecoderDelegate> delegate; |
|||
|
|||
- (instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - format: 解码格式
|
|||
/// - delegate: 代理
|
|||
- (instancetype)initDecoder:(JLOpusFormat *)format delegate:(id<JLOpusDecoderDelegate>)delegate; |
|||
|
|||
/// 重置解码格式
|
|||
/// - Parameter format: 解码格式
|
|||
-(void)resetOpusFramet:(JLOpusFormat *)format; |
|||
|
|||
/// 输入 Opus 数据
|
|||
/// - Parameter data: Opus 数据
|
|||
-(void)opusDecoderInputData:(NSData *)data; |
|||
|
|||
/// 解码文件
|
|||
/// - Parameters:
|
|||
/// - input: opus 文件
|
|||
/// - outPut: 输出路径
|
|||
/// - result: 结果回调
|
|||
-(void)opusDecodeFile:(NSString *)input outPut:(NSString *_Nullable)outPut Resoult:(JLOpusDecoderConvertBlock _Nullable)result; |
|||
|
|||
/// 释放
|
|||
-(void)opusOnRelease; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,83 @@ |
|||
//
|
|||
// JLOpusEncodeConfig.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/8/27.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
typedef NS_ENUM(NSInteger, JLOpusEncoderBandwidth) { |
|||
///(4kHz bandpass)
|
|||
JLOpusEncoderBandwidthNarrowband = 1101, // 对应 OPUS_BANDWIDTH_NARROWBAND
|
|||
/// (6kHz bandpass)
|
|||
JLOpusEncoderBandwidthMediumband = 1102, // 对应 OPUS_BANDWIDTH_MEDIUMBAND
|
|||
/// (8kHz bandpass)
|
|||
JLOpusEncoderBandwidthWideband = 1103, // 对应 OPUS_BANDWIDTH_WIDEBAND
|
|||
/// (12kHz bandpass)
|
|||
JLOpusEncoderBandwidthSuperwideband = 1104,// 对应 OPUS_BANDWIDTH_SUPERWIDEBAND
|
|||
/// (20kHz bandpass)
|
|||
JLOpusEncoderBandwidthFullband = 1105 // 对应 OPUS_BANDWIDTH_FULLBAND
|
|||
}; |
|||
|
|||
@interface JLOpusEncodeConfig : NSObject |
|||
|
|||
/// 采样率
|
|||
@property (nonatomic, assign) int sampleRate; |
|||
|
|||
/// 单/双声道
|
|||
@property (nonatomic, assign) int channels; |
|||
|
|||
/// 帧长度 20ms 默认值
|
|||
@property (nonatomic, assign) int frameDuration; |
|||
|
|||
/// 帧长度
|
|||
@property (nonatomic, assign) int frameSize; |
|||
|
|||
/// BitRate
|
|||
@property (nonatomic, assign) int bitRate; |
|||
|
|||
/// 可变比特率开关,默认 NO(使用 CBR)
|
|||
@property (nonatomic, assign) BOOL useVBR; |
|||
|
|||
/// VBR 限制模式,默认 NO
|
|||
@property (nonatomic, assign) BOOL constrainedVBR; |
|||
|
|||
/// 编码复杂度 0~10,默认 5
|
|||
@property (nonatomic, assign) int complexity; |
|||
|
|||
/// 强制输出声道数 -1: 自适应, 1: 单声道, 2: 双声道, 默认 -1
|
|||
@property (nonatomic, assign) int forceChannels; |
|||
|
|||
/// 是否启用 DTX(静音段不发送数据),默认 NO
|
|||
@property (nonatomic, assign) BOOL useDTX; |
|||
|
|||
/// 网络丢包百分比,默认 0
|
|||
@property (nonatomic, assign) int packetLossPercent; |
|||
|
|||
/// 最大带宽限制(OPUS_BANDWIDTH_*),默认 FULLBAND
|
|||
@property (nonatomic, assign) int bandwidth; |
|||
|
|||
/// PCM 输入有效位深,默认 16
|
|||
@property (nonatomic, assign) int lsbDepth; |
|||
|
|||
/// 专家模式下帧时长(ms),默认与 frameDuration 一致
|
|||
@property (nonatomic, assign) int expertFrameDuration; |
|||
|
|||
/// 是否启用数据头
|
|||
/// 默认是启用的
|
|||
@property (nonatomic, assign) BOOL hasDataHeader; |
|||
|
|||
/// 创建默认编码配置
|
|||
+ (instancetype)defaultConfig; |
|||
|
|||
/// 获取默认配置
|
|||
/// 杰理的无头配置
|
|||
+ (instancetype)defaultJL; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,69 @@ |
|||
//
|
|||
// JLOpusEncoder.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
// Copyright © 2024 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLAudioUnitKit/JLOpusEncodeConfig.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLOpusEncoder; |
|||
|
|||
/// Opus 编码代理
|
|||
@protocol JLOpusEncoderDelegate <NSObject> |
|||
|
|||
/// PCM 数据编码
|
|||
/// - Parameters:
|
|||
/// - encoder: 解码器
|
|||
/// - data: opus 数据
|
|||
/// - error: 错误信息
|
|||
-(void)opusEncoder:(JLOpusEncoder *)encoder Data:(NSData* _Nullable)data error:(NSError* _Nullable)error; |
|||
|
|||
@end |
|||
|
|||
typedef void(^JLOpusEncoderConvertBlock)(NSString *_Nullable pcmPath,NSError *_Nullable error); |
|||
|
|||
/// Opus 编码
|
|||
@interface JLOpusEncoder : NSObject |
|||
|
|||
/// 音频格式
|
|||
@property (nonatomic, strong) JLOpusEncodeConfig *opusFormat; |
|||
|
|||
/// 代理
|
|||
@property (nonatomic, weak) id<JLOpusEncoderDelegate> delegate; |
|||
|
|||
-(instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - config: 音频格式
|
|||
/// - delegate: 代理
|
|||
-(instancetype)initFormat:(JLOpusEncodeConfig *)format delegate:(id<JLOpusEncoderDelegate>)delegate; |
|||
|
|||
/// PCM 数据
|
|||
/// - Parameter data: PCM 数据
|
|||
-(void)opusEncodeData:(NSData *)data; |
|||
|
|||
/// PCM 文件转换成 Opus 文件(推荐新接口,流式读取,避免一次性加载内存)
|
|||
/// - Parameters:
|
|||
/// - pcmPath: PCM 文件存放路径
|
|||
/// - output: 文件输出路径(可空,默认 ~/Documents/pcmToOpus.opus)
|
|||
/// - result: 结果回调,回传输出路径或错误
|
|||
-(void)opusEncodeFile:(NSString *)pcmPath output:(NSString *_Nullable)output result:(JLOpusEncoderConvertBlock _Nullable)result; |
|||
|
|||
/// 兼容旧接口(已废弃:命名拼写问题,且旧实现一次性读入文件)
|
|||
/// - Parameters:
|
|||
/// - pcmPath: PCM 文件存放路径
|
|||
/// - outPut: 文件输出路径
|
|||
/// - result: 结果回调
|
|||
-(void)opusEncodeFile:(NSString *)pcmPath outPut:(NSString *_Nullable)outPut Resoult:(JLOpusEncoderConvertBlock _Nullable)result __attribute__((deprecated("Use opusEncodeFile:output:result: instead."))); |
|||
|
|||
/// 释放
|
|||
-(void)opusOnRelease; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,59 @@ |
|||
//
|
|||
// JLOpusOptions.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
// Copyright © 2024 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
#define OPUS_JL_MAX_FRAME_SIZE 48000 * 2 |
|||
#define OPUS_JL_MAX_PACKET_SIZE 1500 |
|||
|
|||
|
|||
@interface JLOpusFormat : NSObject |
|||
|
|||
/// 采样率
|
|||
@property (nonatomic, assign) int sampleRate; |
|||
|
|||
/// 单/双声道
|
|||
@property (nonatomic, assign) int channels; |
|||
|
|||
/// 帧长度 20ms 默认值
|
|||
@property (nonatomic, assign) int frameDuration; |
|||
|
|||
/// BitRate
|
|||
@property (nonatomic, assign) int bitRate; |
|||
|
|||
/// 数据帧大小
|
|||
@property (nonatomic, assign, readonly) int frameSize; |
|||
|
|||
/// 数据大小
|
|||
@property (nonatomic, assign) int dataSize; |
|||
|
|||
/// 是否包含数据头部
|
|||
@property (nonatomic, assign) BOOL hasDataHeader; |
|||
|
|||
/// 是否开启slik语音优化
|
|||
@property (nonatomic, assign) BOOL usVoipSlik; |
|||
|
|||
|
|||
-(instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 默认配置
|
|||
/// sampleRate: 16000
|
|||
/// channels: 1
|
|||
/// frameDuration: 20
|
|||
/// dataSize: 40
|
|||
/// frameSize: 320
|
|||
/// hasDataHeader: YES
|
|||
/// bitRate: 16000
|
|||
/// usVoipSlik: false
|
|||
+(JLOpusFormat*)defaultFormats; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,67 @@ |
|||
//
|
|||
// JLOpusToOgg.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/5/16.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
typedef void(^JLOpusToOggConvertBlock)(NSData *_Nullable oggData, BOOL isLast, NSError *_Nullable error); |
|||
|
|||
/// 将Opus数据转换为Ogg数据
|
|||
@interface JLOpusToOgg : NSObject |
|||
|
|||
/// 转码内容的回调
|
|||
@property(nonatomic,strong)JLOpusToOggConvertBlock _Nullable convertBlock; |
|||
|
|||
/// 帧长
|
|||
/// - Parameter frameLen: 帧长
|
|||
/// 默认值 40
|
|||
- (instancetype)initWithFrameLength:(uint32_t)frameLen; |
|||
|
|||
/// 开始流
|
|||
-(void)startStream; |
|||
|
|||
/// 添加Opus数据
|
|||
/// - Parameter opusData: 符合杰理的无头裸 opus 数据
|
|||
- (void)appendOpusData:(NSData *)opusData; |
|||
|
|||
/// 关闭流
|
|||
- (void)closeStream; |
|||
|
|||
|
|||
/// 将Opus数据转换为Ogg数据
|
|||
/// opus 必须为 16000
|
|||
/// opus 必须是 单声道
|
|||
/// - Parameters:
|
|||
/// - opusData: 符合杰理的无头裸 opus 数据
|
|||
/// - frameLen: 帧长 公版默认帧长是 40
|
|||
/// - duration: 转换后的时长
|
|||
/// - error: 错误
|
|||
+ (NSData *_Nullable)convertOpusDataToOgg:(NSData *)opusData |
|||
frameLen:(uint32_t)frameLen |
|||
duration:(double *)duration |
|||
error:(NSError *__autoreleasing _Nullable *)error ; |
|||
|
|||
/// 将Opus文件转换为Ogg文件
|
|||
/// 符合杰理的无头裸 opus 文件
|
|||
/// opus 必须为 16000
|
|||
/// opus 必须是 单声道
|
|||
/// - Parameters:
|
|||
/// - opusFilePath: opus文件路径
|
|||
/// - oggFilePath: ogg文件路径
|
|||
/// - frameLen: 帧长 公版默认帧长是 40
|
|||
/// - duration: 转换后的时长
|
|||
+(void)convertOpusFileToOgg:(NSString *)opusFilePath |
|||
oggFilePath:(NSString *)oggFilePath |
|||
frameLen:(uint32_t)frameLen |
|||
duration:(double *)duration; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,55 @@ |
|||
//
|
|||
// JLPcmToWav.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/4/15.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// PCM 转 WAV
|
|||
@interface JLPcmToWav : NSObject |
|||
|
|||
#pragma mark - 流式编码接口 |
|||
|
|||
/// 初始化流式编码器
|
|||
/// @param outputPath 输出文件路径
|
|||
/// @param sampleRate 采样率(如 16000)
|
|||
/// @param numChannels 声道数(1 或 2)
|
|||
/// @param bitsPerSample 位深(16)
|
|||
- (instancetype)initWithOutputPath:(NSString *)outputPath |
|||
sampleRate:(uint32_t)sampleRate |
|||
numChannels:(uint16_t)numChannels |
|||
bitsPerSample:(uint16_t)bitsPerSample; |
|||
|
|||
/// 追加 PCM 数据(需确保数据格式与初始化参数一致)
|
|||
/// @param pcmData PCM 数据块
|
|||
/// @param error 错误信息
|
|||
- (BOOL)appendPCMData:(NSData *)pcmData error:(NSError **)error; |
|||
|
|||
/// 完成编码并关闭文件(必须调用以更新 WAV 头)
|
|||
/// @param error 错误信息
|
|||
- (BOOL)finishWithError:(NSError **)error; |
|||
|
|||
#pragma mark - 一次性编码接口(便捷方法) |
|||
|
|||
/// 将 PCM 数据一次性转为 WAV 文件
|
|||
/// @param pcmData PCM 数据块
|
|||
/// @param outputPath 输出文件路径
|
|||
/// @param sampleRate 采样率(如 16000)
|
|||
/// @param numChannels 声道数(1 或 2)
|
|||
/// @param bitsPerSample 位深(16)
|
|||
/// @param error 错误信息
|
|||
+ (BOOL)convertPCMData:(NSData *)pcmData |
|||
toWAVFile:(NSString *)outputPath |
|||
sampleRate:(uint32_t)sampleRate |
|||
numChannels:(uint16_t)numChannels |
|||
bitsPerSample:(uint16_t)bitsPerSample |
|||
error:(NSError **)error; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,51 @@ |
|||
//
|
|||
// JLPcmToWtg.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2025/1/21.
|
|||
// Copyright © 2025 ZhuHai JieLi Technology Co.,Ltd. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
@interface JLPcm2WtgModel : NSObject <NSCopying> |
|||
|
|||
/// 音频文件
|
|||
@property (nonatomic, copy) NSString *pcmPath; |
|||
|
|||
/// 输出文件
|
|||
@property (nonatomic, copy) NSString *wtgPath; |
|||
|
|||
@end |
|||
|
|||
|
|||
/// JLPcmToWtgProtocol
|
|||
@protocol JLPcmToWtgDelegate <NSObject> |
|||
|
|||
/// 音频转码完成
|
|||
/// - Parameter model: 音频转码模型
|
|||
- (void)convertPcmToWtgDone:(JLPcm2WtgModel *)model; |
|||
|
|||
@end |
|||
|
|||
/// 音频转码
|
|||
/// PCM 转 WTG
|
|||
@interface JLPcmToWtg : NSObject |
|||
|
|||
- (instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 音频转码初始化
|
|||
/// - Parameter delegate: 音频转码代理
|
|||
- (instancetype)initWithDelegate:(id<JLPcmToWtgDelegate>)delegate; |
|||
|
|||
/// 音频转码
|
|||
/// 当前接口模型只限制 PCM 文件格式为:8k 16bit
|
|||
/// 输入的pcm文件(16bit,小端,8k采样率),wtg_filename:输出的wtg文件
|
|||
/// - Parameter model: 音频转码模型
|
|||
-(void)convertPcmToWtg:(JLPcm2WtgModel *)model; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,54 @@ |
|||
//
|
|||
// JLSpeexUnit.h
|
|||
// JLAudioUnitKit
|
|||
//
|
|||
// Created by EzioChan on 2024/11/14.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLSpeexDecoder; |
|||
|
|||
@protocol JLSpeexDelegate <NSObject> |
|||
|
|||
/// Speex 数据解码
|
|||
/// - Parameters:
|
|||
/// - decoder: 解码器
|
|||
/// - data: PCM 数据
|
|||
/// - error: 错误信息
|
|||
- (void)speexDecoder:(JLSpeexDecoder *)decoder Data:(NSData* _Nullable)data error:(NSError* _Nullable)error; |
|||
|
|||
@end |
|||
|
|||
typedef void(^JLSpeexConvertBlock)(NSString *_Nullable pcmPath,NSError *_Nullable error); |
|||
|
|||
/// Speex 数据解码
|
|||
@interface JLSpeexDecoder : NSObject |
|||
|
|||
-(instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/// 初始化
|
|||
/// - Parameter delegate: 委托
|
|||
-(instancetype)initWithDelegate:(id<JLSpeexDelegate>)delegate; |
|||
|
|||
/// 委托
|
|||
@property (nonatomic, weak) id<JLSpeexDelegate> delegate; |
|||
|
|||
/// 输入 Speex 数据
|
|||
/// - Parameter data: Speex 数据
|
|||
-(void)speexInputData:(NSData*)data; |
|||
|
|||
/// 将 Speex 转换为 PCM
|
|||
/// - Parameters:
|
|||
/// - filePath: Speex 路径
|
|||
/// - opPath: 输出路径
|
|||
/// - result: 结果回调
|
|||
-(void)speexConvertToPcm:(NSString *)filePath outPutFilePath:(NSString * _Nullable)opPath Result:(JLSpeexConvertBlock)result; |
|||
|
|||
/// 释放对象
|
|||
-(void)speexOnRelease; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
framework module JLAudioUnitKit { |
|||
umbrella header "JLAudioUnitKit.h" |
|||
export * |
|||
|
|||
module * { export * } |
|||
} |
|||
@ -0,0 +1,234 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>files</key> |
|||
<dict> |
|||
<key>Headers/JLAudioUnitKit.h</key> |
|||
<data> |
|||
hE2nr+4q2/NdSgBaayJc7ZoOXb0= |
|||
</data> |
|||
<key>Headers/JLAudioUnitPlayer.h</key> |
|||
<data> |
|||
QPMLV/XA8hjk39d+vT+S57t0fDU= |
|||
</data> |
|||
<key>Headers/JLOpusDecoder.h</key> |
|||
<data> |
|||
K1bYcaJ67prImNlGuldy8csTRHc= |
|||
</data> |
|||
<key>Headers/JLOpusEncodeConfig.h</key> |
|||
<data> |
|||
NArAew5QxnSJGsD0tRzQ2V7bHrY= |
|||
</data> |
|||
<key>Headers/JLOpusEncoder.h</key> |
|||
<data> |
|||
7DYUlvXrp1QC9l2XZ5tNHtsmsBQ= |
|||
</data> |
|||
<key>Headers/JLOpusFormat.h</key> |
|||
<data> |
|||
Du1x3VNk87NstmspRk7ElijuZrk= |
|||
</data> |
|||
<key>Headers/JLOpusToOgg.h</key> |
|||
<data> |
|||
fSJT6LcyylJHTHX1wsN3JHG2FxU= |
|||
</data> |
|||
<key>Headers/JLPcmToWav.h</key> |
|||
<data> |
|||
/BbZmqmWpWVBusXqjnzbjaBNCNg= |
|||
</data> |
|||
<key>Headers/JLPcmToWtg.h</key> |
|||
<data> |
|||
zoOdOFpIulND0F1OrfIXR1H0kh0= |
|||
</data> |
|||
<key>Headers/JLSpeexDecoder.h</key> |
|||
<data> |
|||
5ecBKtD3BDGccLiKpTs0fS0CSgs= |
|||
</data> |
|||
<key>Info.plist</key> |
|||
<data> |
|||
pXqOzYCqPnMLY0nonWZTcbfnlhU= |
|||
</data> |
|||
<key>Modules/module.modulemap</key> |
|||
<data> |
|||
2vYf0m+hGTOTapX6sliv/F1E1VI= |
|||
</data> |
|||
<key>readme.txt</key> |
|||
<data> |
|||
wijZX0Dr2OlODWS6XYbpeKabb7g= |
|||
</data> |
|||
</dict> |
|||
<key>files2</key> |
|||
<dict> |
|||
<key>Headers/JLAudioUnitKit.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
J5pq6Ed3fR+cQ7CGPXDoPl7BZzix7Cjf5yJZFRRvxqs= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLAudioUnitPlayer.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
qBz0OA82HUH4kBtO8xiUw7Q4ohtiIvCSYfCqax5xjJY= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLOpusDecoder.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
cnAj6Nt6vgRLoEH6QY3Q+gYpjcxGPN1OLLZbCgdLymI= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLOpusEncodeConfig.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
qrPpsrXaNCvyxf0/gUZtvveL+ywsfgBUrMPFibjneOo= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLOpusEncoder.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
YoHsvoGH2VEjvEIzEa7t+cAnzf8kHEU3dJTd03ABr1w= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLOpusFormat.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
Nm6vM9/EbFzyIWbsysu6EOO2S+vZVeplcop4NvoJaMA= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLOpusToOgg.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
dNSvJJnED/6E1p7TYZ4zBzUnLDVsZ8NovuNYjge6T/w= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLPcmToWav.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
l/SEQhSFh7ctq/pBV+Z7X+Z0/gz30eCw3s31otjMPho= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLPcmToWtg.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
MwtbX3Sa0nytA+m11x+1rDvP4WvJnZLljshuT5B3WD0= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLSpeexDecoder.h</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
pV0X3xn07Ps7wE+0EfL9Yu/08tp8Ug8s14iDigRU46o= |
|||
</data> |
|||
</dict> |
|||
<key>Modules/module.modulemap</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
akFCUM59aSAaRM/ADWQ138YT9GD3oAjcaTvTUo24Ml8= |
|||
</data> |
|||
</dict> |
|||
<key>readme.txt</key> |
|||
<dict> |
|||
<key>hash2</key> |
|||
<data> |
|||
+2GG9ORrf2yJnBe2joKWtyBZL9p2sCH8EXqK1GIgW0E= |
|||
</data> |
|||
</dict> |
|||
</dict> |
|||
<key>rules</key> |
|||
<dict> |
|||
<key>^.*</key> |
|||
<true/> |
|||
<key>^.*\.lproj/</key> |
|||
<dict> |
|||
<key>optional</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1000</real> |
|||
</dict> |
|||
<key>^.*\.lproj/locversion.plist$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1100</real> |
|||
</dict> |
|||
<key>^Base\.lproj/</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>1010</real> |
|||
</dict> |
|||
<key>^version.plist$</key> |
|||
<true/> |
|||
</dict> |
|||
<key>rules2</key> |
|||
<dict> |
|||
<key>.*\.dSYM($|/)</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>11</real> |
|||
</dict> |
|||
<key>^(.*/)?\.DS_Store$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>2000</real> |
|||
</dict> |
|||
<key>^.*</key> |
|||
<true/> |
|||
<key>^.*\.lproj/</key> |
|||
<dict> |
|||
<key>optional</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1000</real> |
|||
</dict> |
|||
<key>^.*\.lproj/locversion.plist$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1100</real> |
|||
</dict> |
|||
<key>^Base\.lproj/</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>1010</real> |
|||
</dict> |
|||
<key>^Info\.plist$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
<key>^PkgInfo$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
<key>^embedded\.provisionprofile$</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
<key>^version\.plist$</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
</dict> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1,52 @@ |
|||
DESCRIPTION |
|||
----------- |
|||
This package includes the files needed to build the fixed point implementation |
|||
of the ITU-T G.729 Appendix IV. |
|||
|
|||
DIFFERENCES WITH G.729B |
|||
----------------------- |
|||
The ANSI-C source code simulating the bit-exact, fixed point simulation |
|||
software of enhanced VAD is integrated into the G.729B source code. |
|||
The modification to the G.729B source code updated files of coder.c, |
|||
cod_ld8k.c, bits.c, dec_sid.c, dtx.c, qsidgain.c, qsidlsf.c, tab_dtx.c, |
|||
tab_dtx.h, ld8k.h, deleted vad.c/h and integrated the enhanced VAD functions |
|||
into the G.729B project. The modification also replaced the original basic |
|||
operators used in the original G.729B source code by the basic operators of |
|||
ITU-T Software Tool Library STL2005. |
|||
|
|||
COMPILATION |
|||
----------- |
|||
For UNIX systems the following makefiles are provided |
|||
|
|||
coder.mak |
|||
decoder.mak |
|||
|
|||
Edit the makefiles coder.mak and decoder.mak to set the proper options |
|||
for your system. |
|||
The command to compile and link all code on a UNIX system is |
|||
|
|||
make -f coder.mak |
|||
make -f decoder.mak |
|||
|
|||
For other platforms, the *.mak files can be used to work out the |
|||
compilation procedures. |
|||
|
|||
USAGE |
|||
----- |
|||
The command line instruction for the encoder is as follows: |
|||
coder inputfile bitstreamfile dtx_option mode x |
|||
where: |
|||
inputfile : 8 kHz sampled data file containing 16 bit linear PCM signal |
|||
bitstreamfile: binary file containing bitstream |
|||
dtx_option : = 1 : DTX enabled 0 : DTX disabled |
|||
mode X : Run encoder with enhanced VAD in operating point X, |
|||
X=0 or 1 or 2 representing balanced or quality-preferred |
|||
or bandwidth saving operating point, respectively |
|||
|
|||
The command line for the decoder is as follows: |
|||
decoder bitstreamfile outputfile |
|||
where: |
|||
bitstreamfile: binary file containing bitstream |
|||
outputfile : 8 kHz sampled data file containing 16 bit linear PCM signal |
|||
|
|||
|
|||
@ -0,0 +1,59 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>AvailableLibraries</key> |
|||
<array> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLBmpConvertKit.framework/JLBmpConvertKit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>ios-arm64</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLBmpConvertKit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>arm64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>ios</string> |
|||
</dict> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLBmpConvertKit.framework/Versions/A/JLBmpConvertKit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>macos-arm64_x86_64</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLBmpConvertKit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>arm64</string> |
|||
<string>x86_64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>macos</string> |
|||
</dict> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLBmpConvertKit.framework/JLBmpConvertKit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>ios-arm64_x86_64-simulator</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLBmpConvertKit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>arm64</string> |
|||
<string>x86_64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>ios</string> |
|||
<key>SupportedPlatformVariant</key> |
|||
<string>simulator</string> |
|||
</dict> |
|||
</array> |
|||
<key>CFBundlePackageType</key> |
|||
<string>XFWK</string> |
|||
<key>XCFrameworkFormatVersion</key> |
|||
<string>1.0</string> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1,95 @@ |
|||
//
|
|||
// JLBmpCovert.h
|
|||
// JLBmpCovertKit
|
|||
//
|
|||
// Created by EzioChan on 2024/9/9.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLBmpConvertKit/JLBmpConvertKit.h> |
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
#import <UIKit/UIKit.h> |
|||
#elif TARGET_OS_OSX |
|||
#import <AppKit/AppKit.h> |
|||
#endif |
|||
|
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLImageConvertResult; |
|||
|
|||
typedef void(^JLBmpCovertCallBack)(NSString *inFilePath,NSString *__nullable outFilePath,NSError *__nullable error) __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
typedef void(^JLBmpCovertCallBack2)(NSData *__nullable outFileData,NSError *__nullable error) __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
|
|||
/// 图像转换
|
|||
@interface JLBmpConvert : NSObject |
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - type: 转换类型
|
|||
/// - inFilePath: 输入文件
|
|||
/// - outFilePath: 输出文件
|
|||
/// - completion: 回调
|
|||
+(void)covert:(JLBmpConvertType)type |
|||
inFilePath:(NSString *_Nonnull)inFilePath |
|||
outFilePath:(NSString * __nullable)outFilePath |
|||
completion:(JLBmpCovertCallBack _Nonnull)completion __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - type: 转换类型
|
|||
/// - inImage: 输入图片
|
|||
/// - completion: 回调
|
|||
+(void)covert:(JLBmpConvertType)type |
|||
Image:(UIImage *)inImage |
|||
completion:(JLBmpCovertCallBack2 _Nonnull)completion __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - option: 类型
|
|||
/// 当前仅仅 707N 系列芯片可指定图像格式
|
|||
/// - inFilePath: 输入文件
|
|||
/// - outFilePath: 输出文件
|
|||
/// 文件路径转换入口
|
|||
+ (JLImageConvertResult *)convert:(JLBmpConvertOption *)option |
|||
inFilePath:(NSString *)inFilePath |
|||
outFilePath:(NSString * __nullable)outFilePath; |
|||
|
|||
/// UIImage 转换
|
|||
/// 当前仅仅 707N 系列芯片可指定图像格式
|
|||
/// - Parameters:
|
|||
/// - option: 类型
|
|||
/// - imgData: 图片的原始数据
|
|||
+(JLImageConvertResult *)convert:(JLBmpConvertOption *)option ImageData:(NSData *)imgData; |
|||
|
|||
|
|||
/// UIImage 转换成 BGRA
|
|||
/// - Parameter image: 图片
|
|||
+(NSData*)convertImageToBGRABytes:(UIImage *)image; |
|||
|
|||
/// UIImage 转换成 RGBA
|
|||
/// - Parameter image: 图片
|
|||
+(NSData*)convertImageToRGBABytes:(UIImage *)image; |
|||
|
|||
|
|||
/// 图片缩放
|
|||
/// - Parameters:
|
|||
/// - image: 图片
|
|||
/// - newSize: 缩放大小
|
|||
/// - Returns: 缩放后的图片
|
|||
+(NSData *)resizeImage:(UIImage*)image andResizeTo:(CGSize)newSize; |
|||
|
|||
#elif TARGET_OS_OSX |
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - option: 转换类型
|
|||
/// - inImage: 输入图片
|
|||
+(JLImageConvertResult *)convert:(JLBmpConvertOption *)option Image:(NSImage *)image; |
|||
|
|||
#endif |
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,24 @@ |
|||
//
|
|||
// JLBmpConvertKit.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2024/9/9.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLBmpConvertKit.
|
|||
FOUNDATION_EXPORT double JLBmpConvertKitVersionNumber; |
|||
|
|||
//! Project version string for JLBmpConvertKit.
|
|||
FOUNDATION_EXPORT const unsigned char JLBmpConvertKitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLBmpConvertKit/PublicHeader.h>
|
|||
|
|||
|
|||
#import <JLBmpConvertKit/JLBmpConvertOption.h> |
|||
#import <JLBmpConvertKit/JLBmpConvert.h> |
|||
#import <JLBmpConvertKit/JLGifBin.h> |
|||
#import <JLBmpConvertKit/JLImageConvertResult.h> |
|||
|
|||
@ -0,0 +1,89 @@ |
|||
//
|
|||
// JLBmpConvertOption.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2025/5/23.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// 图像转换类型
|
|||
typedef NS_ENUM(NSUInteger, JLBmpConvertType) { |
|||
/// 695N 图像转换 RGB 转换成 695N 芯片对应的图像资源
|
|||
/// 对应原 BR23 转换算法
|
|||
JLBmpConvertType695N_RBG = 0, |
|||
/// 701N 图像转换 RGB 转换成 701N 芯片对应的图像资源
|
|||
/// 对应原 BR28 转换的算法
|
|||
JLBmpConvertType701N_RBG = 1, |
|||
/// 701N 图像转换 ARGB 转换成 701N 芯片对应的图像资源
|
|||
/// 对应原 BR28_ARBG 转换的算法
|
|||
JLBmpConvertType701N_ARBG = 2, |
|||
/// 701N 图像转换 RGB 转换成 701N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应原 BR28_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType701N_RBG_NO_PACK = 3, |
|||
/// 701N 图像转换 ARGB 转换成 701N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应原 BR28_ARGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType701N_ARGB_NO_PACK = 4, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源
|
|||
/// 对应 BR35 转换的算法
|
|||
JLBmpConvertType707N_RBG = 5, |
|||
/// 707N 图像转换 ARGB 转换成 707N 芯片对应的图像资源
|
|||
/// 对应 BR35_ARGB 转换的算法
|
|||
JLBmpConvertType707N_ARGB = 6, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应 BR35_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType707N_ARGB_NO_PACK = 7, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应 BR35_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType707N_RBG_NO_PACK = 8, |
|||
/// 701N 图像转换 JPEG
|
|||
/// 仅仅支持 JPEG 类型
|
|||
JLBmpConvertType701N_JPEG = 9 |
|||
}; |
|||
|
|||
/// 图像格式
|
|||
/// 仅(707N 系列芯片支持)
|
|||
typedef NS_ENUM(NSUInteger, JLBmpPixelformat) { |
|||
/// ARBG8888/RBG888 格式
|
|||
JLBmpPixelformat_888, |
|||
/// ARBG8565/RBG565 格式
|
|||
JLBmpPixelformat_565, |
|||
/// 自动选择最小的格式
|
|||
JLBmpPixelformat_Auto, |
|||
}; |
|||
|
|||
/// LVGL 打包格式
|
|||
typedef NS_ENUM(NSUInteger, JLBmpPacketFormat) { |
|||
JLBmpPacketFormatNone = 0, |
|||
JLBmpPacketFormatJLUI = 1, |
|||
JLBmpPacketFormatLVGL = 2 |
|||
}; |
|||
|
|||
/// 图像转换选项
|
|||
@interface JLBmpConvertOption : NSObject |
|||
|
|||
/// 图像转换类型
|
|||
@property (nonatomic, assign) JLBmpConvertType convertType; |
|||
|
|||
/// 图像格式
|
|||
/// 默认为 auto
|
|||
/// 仅(707N 系列芯片支持)
|
|||
@property (nonatomic, assign) JLBmpPixelformat pixelformat; |
|||
|
|||
/// LVGL 打包格式
|
|||
/// 默认为 JLUI
|
|||
/// 仅(707N 系列芯片支持)
|
|||
@property (nonatomic, assign) JLBmpPacketFormat packetFormat; |
|||
|
|||
/// 是否转换成 BGRA
|
|||
/// 当使用的是 JL 的 UI 框架时需要使用
|
|||
/// 使用其他第三方框架时,需要根据固件端框架进行调整
|
|||
/// default YES
|
|||
@property (nonatomic, assign) BOOL convertToBGRA; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,77 @@ |
|||
//
|
|||
// JLGifBin.h
|
|||
// JLGifLib
|
|||
//
|
|||
// Created by EzioChan on 2024/1/18.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// Gif 转 Bin 支持的芯片类型
|
|||
typedef NS_ENUM(NSUInteger, JLGIFBinChipType) { |
|||
/// 701N
|
|||
JLGIFBinChipJL_701N, |
|||
/// 707N
|
|||
JLGIFBinChipJL_707N, |
|||
}; |
|||
|
|||
///packet 是否打包
|
|||
typedef NS_ENUM(NSInteger, JLGIFBinPackageType) { |
|||
/// 不做其他打包使用源数据,适用 LVGL 的公版UI框架
|
|||
JLGIFBinPackageTypeLVGL = 0, |
|||
/// 杰理打包格式,适用 JLVGL 的杰理定制版 UI 框架
|
|||
JLGIFBinPackageTypeJLVGL = 1, |
|||
}; |
|||
|
|||
typedef void(^JLGif2BinBlock)(int code,NSData *_Nullable binData); |
|||
|
|||
/// Gif 转 Bin
|
|||
@interface JLGifBin : NSObject |
|||
|
|||
/// 打印当前SDK的版本
|
|||
+(void)sdkVersion; |
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率
|
|||
/// 3: 高码率
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level Result:(JLGif2BinBlock)block __attribute__((deprecated("Use makeDataToBin:Level:ChipType:Result: instead."))); |
|||
|
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// 3: 高码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// - chip: 芯片类型
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level ChipType:(JLGIFBinChipType)chip Result:(JLGif2BinBlock)block __attribute__((deprecated("Use makeDataToBin:Level:ChipType:PackageType:Result: instead."))); |
|||
|
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// 3: 高码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// - chip: 芯片类型
|
|||
/// - packageType: 打包类型
|
|||
/// 1: JLUI 杰理 UI 格式
|
|||
/// 0: 无 不打包
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level ChipType:(JLGIFBinChipType)chip PackageType:(JLGIFBinPackageType)packageType Result:(JLGif2BinBlock)block; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,34 @@ |
|||
//
|
|||
// JLImageConvertResult.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/6.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// 图像转换结果
|
|||
@interface JLImageConvertResult : NSObject |
|||
/// 结果码
|
|||
@property (nonatomic, assign) int result; |
|||
/// 数据大小
|
|||
@property (nonatomic, assign) int buf_size; |
|||
/// 图像格式
|
|||
@property (nonatomic, assign) int pixel_format; |
|||
/// 压缩模式
|
|||
@property (nonatomic, assign) int compress_mode; |
|||
|
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
/// 输出文件路径
|
|||
@property (nullable, nonatomic, copy) NSString *outFilePath; |
|||
#endif |
|||
|
|||
/// 输出文件内容
|
|||
@property (nullable, nonatomic, copy) NSData *outFileData; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
framework module JLBmpConvertKit { |
|||
umbrella header "JLBmpConvertKit.h" |
|||
export * |
|||
|
|||
module * { export * } |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
//
|
|||
// JLBmpCovert.h
|
|||
// JLBmpCovertKit
|
|||
//
|
|||
// Created by EzioChan on 2024/9/9.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLBmpConvertKit/JLBmpConvertKit.h> |
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
#import <UIKit/UIKit.h> |
|||
#elif TARGET_OS_OSX |
|||
#import <AppKit/AppKit.h> |
|||
#endif |
|||
|
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLImageConvertResult; |
|||
|
|||
typedef void(^JLBmpCovertCallBack)(NSString *inFilePath,NSString *__nullable outFilePath,NSError *__nullable error) __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
typedef void(^JLBmpCovertCallBack2)(NSData *__nullable outFileData,NSError *__nullable error) __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
|
|||
/// 图像转换
|
|||
@interface JLBmpConvert : NSObject |
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - type: 转换类型
|
|||
/// - inFilePath: 输入文件
|
|||
/// - outFilePath: 输出文件
|
|||
/// - completion: 回调
|
|||
+(void)covert:(JLBmpConvertType)type |
|||
inFilePath:(NSString *_Nonnull)inFilePath |
|||
outFilePath:(NSString * __nullable)outFilePath |
|||
completion:(JLBmpCovertCallBack _Nonnull)completion __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - type: 转换类型
|
|||
/// - inImage: 输入图片
|
|||
/// - completion: 回调
|
|||
+(void)covert:(JLBmpConvertType)type |
|||
Image:(UIImage *)inImage |
|||
completion:(JLBmpCovertCallBack2 _Nonnull)completion __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - option: 类型
|
|||
/// 当前仅仅 707N 系列芯片可指定图像格式
|
|||
/// - inFilePath: 输入文件
|
|||
/// - outFilePath: 输出文件
|
|||
/// 文件路径转换入口
|
|||
+ (JLImageConvertResult *)convert:(JLBmpConvertOption *)option |
|||
inFilePath:(NSString *)inFilePath |
|||
outFilePath:(NSString * __nullable)outFilePath; |
|||
|
|||
/// UIImage 转换
|
|||
/// 当前仅仅 707N 系列芯片可指定图像格式
|
|||
/// - Parameters:
|
|||
/// - option: 类型
|
|||
/// - imgData: 图片的原始数据
|
|||
+(JLImageConvertResult *)convert:(JLBmpConvertOption *)option ImageData:(NSData *)imgData; |
|||
|
|||
|
|||
/// UIImage 转换成 BGRA
|
|||
/// - Parameter image: 图片
|
|||
+(NSData*)convertImageToBGRABytes:(UIImage *)image; |
|||
|
|||
/// UIImage 转换成 RGBA
|
|||
/// - Parameter image: 图片
|
|||
+(NSData*)convertImageToRGBABytes:(UIImage *)image; |
|||
|
|||
|
|||
/// 图片缩放
|
|||
/// - Parameters:
|
|||
/// - image: 图片
|
|||
/// - newSize: 缩放大小
|
|||
/// - Returns: 缩放后的图片
|
|||
+(NSData *)resizeImage:(UIImage*)image andResizeTo:(CGSize)newSize; |
|||
|
|||
#elif TARGET_OS_OSX |
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - option: 转换类型
|
|||
/// - inImage: 输入图片
|
|||
+(JLImageConvertResult *)convert:(JLBmpConvertOption *)option Image:(NSImage *)image; |
|||
|
|||
#endif |
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,24 @@ |
|||
//
|
|||
// JLBmpConvertKit.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2024/9/9.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLBmpConvertKit.
|
|||
FOUNDATION_EXPORT double JLBmpConvertKitVersionNumber; |
|||
|
|||
//! Project version string for JLBmpConvertKit.
|
|||
FOUNDATION_EXPORT const unsigned char JLBmpConvertKitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLBmpConvertKit/PublicHeader.h>
|
|||
|
|||
|
|||
#import <JLBmpConvertKit/JLBmpConvertOption.h> |
|||
#import <JLBmpConvertKit/JLBmpConvert.h> |
|||
#import <JLBmpConvertKit/JLGifBin.h> |
|||
#import <JLBmpConvertKit/JLImageConvertResult.h> |
|||
|
|||
@ -0,0 +1,89 @@ |
|||
//
|
|||
// JLBmpConvertOption.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2025/5/23.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// 图像转换类型
|
|||
typedef NS_ENUM(NSUInteger, JLBmpConvertType) { |
|||
/// 695N 图像转换 RGB 转换成 695N 芯片对应的图像资源
|
|||
/// 对应原 BR23 转换算法
|
|||
JLBmpConvertType695N_RBG = 0, |
|||
/// 701N 图像转换 RGB 转换成 701N 芯片对应的图像资源
|
|||
/// 对应原 BR28 转换的算法
|
|||
JLBmpConvertType701N_RBG = 1, |
|||
/// 701N 图像转换 ARGB 转换成 701N 芯片对应的图像资源
|
|||
/// 对应原 BR28_ARBG 转换的算法
|
|||
JLBmpConvertType701N_ARBG = 2, |
|||
/// 701N 图像转换 RGB 转换成 701N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应原 BR28_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType701N_RBG_NO_PACK = 3, |
|||
/// 701N 图像转换 ARGB 转换成 701N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应原 BR28_ARGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType701N_ARGB_NO_PACK = 4, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源
|
|||
/// 对应 BR35 转换的算法
|
|||
JLBmpConvertType707N_RBG = 5, |
|||
/// 707N 图像转换 ARGB 转换成 707N 芯片对应的图像资源
|
|||
/// 对应 BR35_ARGB 转换的算法
|
|||
JLBmpConvertType707N_ARGB = 6, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应 BR35_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType707N_ARGB_NO_PACK = 7, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应 BR35_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType707N_RBG_NO_PACK = 8, |
|||
/// 701N 图像转换 JPEG
|
|||
/// 仅仅支持 JPEG 类型
|
|||
JLBmpConvertType701N_JPEG = 9 |
|||
}; |
|||
|
|||
/// 图像格式
|
|||
/// 仅(707N 系列芯片支持)
|
|||
typedef NS_ENUM(NSUInteger, JLBmpPixelformat) { |
|||
/// ARBG8888/RBG888 格式
|
|||
JLBmpPixelformat_888, |
|||
/// ARBG8565/RBG565 格式
|
|||
JLBmpPixelformat_565, |
|||
/// 自动选择最小的格式
|
|||
JLBmpPixelformat_Auto, |
|||
}; |
|||
|
|||
/// LVGL 打包格式
|
|||
typedef NS_ENUM(NSUInteger, JLBmpPacketFormat) { |
|||
JLBmpPacketFormatNone = 0, |
|||
JLBmpPacketFormatJLUI = 1, |
|||
JLBmpPacketFormatLVGL = 2 |
|||
}; |
|||
|
|||
/// 图像转换选项
|
|||
@interface JLBmpConvertOption : NSObject |
|||
|
|||
/// 图像转换类型
|
|||
@property (nonatomic, assign) JLBmpConvertType convertType; |
|||
|
|||
/// 图像格式
|
|||
/// 默认为 auto
|
|||
/// 仅(707N 系列芯片支持)
|
|||
@property (nonatomic, assign) JLBmpPixelformat pixelformat; |
|||
|
|||
/// LVGL 打包格式
|
|||
/// 默认为 JLUI
|
|||
/// 仅(707N 系列芯片支持)
|
|||
@property (nonatomic, assign) JLBmpPacketFormat packetFormat; |
|||
|
|||
/// 是否转换成 BGRA
|
|||
/// 当使用的是 JL 的 UI 框架时需要使用
|
|||
/// 使用其他第三方框架时,需要根据固件端框架进行调整
|
|||
/// default YES
|
|||
@property (nonatomic, assign) BOOL convertToBGRA; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,77 @@ |
|||
//
|
|||
// JLGifBin.h
|
|||
// JLGifLib
|
|||
//
|
|||
// Created by EzioChan on 2024/1/18.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// Gif 转 Bin 支持的芯片类型
|
|||
typedef NS_ENUM(NSUInteger, JLGIFBinChipType) { |
|||
/// 701N
|
|||
JLGIFBinChipJL_701N, |
|||
/// 707N
|
|||
JLGIFBinChipJL_707N, |
|||
}; |
|||
|
|||
///packet 是否打包
|
|||
typedef NS_ENUM(NSInteger, JLGIFBinPackageType) { |
|||
/// 不做其他打包使用源数据,适用 LVGL 的公版UI框架
|
|||
JLGIFBinPackageTypeLVGL = 0, |
|||
/// 杰理打包格式,适用 JLVGL 的杰理定制版 UI 框架
|
|||
JLGIFBinPackageTypeJLVGL = 1, |
|||
}; |
|||
|
|||
typedef void(^JLGif2BinBlock)(int code,NSData *_Nullable binData); |
|||
|
|||
/// Gif 转 Bin
|
|||
@interface JLGifBin : NSObject |
|||
|
|||
/// 打印当前SDK的版本
|
|||
+(void)sdkVersion; |
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率
|
|||
/// 3: 高码率
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level Result:(JLGif2BinBlock)block __attribute__((deprecated("Use makeDataToBin:Level:ChipType:Result: instead."))); |
|||
|
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// 3: 高码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// - chip: 芯片类型
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level ChipType:(JLGIFBinChipType)chip Result:(JLGif2BinBlock)block __attribute__((deprecated("Use makeDataToBin:Level:ChipType:PackageType:Result: instead."))); |
|||
|
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// 3: 高码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// - chip: 芯片类型
|
|||
/// - packageType: 打包类型
|
|||
/// 1: JLUI 杰理 UI 格式
|
|||
/// 0: 无 不打包
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level ChipType:(JLGIFBinChipType)chip PackageType:(JLGIFBinPackageType)packageType Result:(JLGif2BinBlock)block; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,34 @@ |
|||
//
|
|||
// JLImageConvertResult.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/6.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// 图像转换结果
|
|||
@interface JLImageConvertResult : NSObject |
|||
/// 结果码
|
|||
@property (nonatomic, assign) int result; |
|||
/// 数据大小
|
|||
@property (nonatomic, assign) int buf_size; |
|||
/// 图像格式
|
|||
@property (nonatomic, assign) int pixel_format; |
|||
/// 压缩模式
|
|||
@property (nonatomic, assign) int compress_mode; |
|||
|
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
/// 输出文件路径
|
|||
@property (nullable, nonatomic, copy) NSString *outFilePath; |
|||
#endif |
|||
|
|||
/// 输出文件内容
|
|||
@property (nullable, nonatomic, copy) NSData *outFileData; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
framework module JLBmpConvertKit { |
|||
umbrella header "JLBmpConvertKit.h" |
|||
export * |
|||
|
|||
module * { export * } |
|||
} |
|||
@ -0,0 +1,192 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>files</key> |
|||
<dict> |
|||
<key>Headers/JLBmpConvert.h</key> |
|||
<data> |
|||
5urDCSjpqHBbBhVbnkpZDUAqfUQ= |
|||
</data> |
|||
<key>Headers/JLBmpConvertKit.h</key> |
|||
<data> |
|||
rJo680NKOdjmobcOdHzU3oQ05lQ= |
|||
</data> |
|||
<key>Headers/JLBmpConvertOption.h</key> |
|||
<data> |
|||
bPMnU/cb1ZNEvx+6wLH+tNggsWM= |
|||
</data> |
|||
<key>Headers/JLGifBin.h</key> |
|||
<data> |
|||
+UKivjyP0JG0+mVZPKUAWwhParQ= |
|||
</data> |
|||
<key>Headers/JLImageConvertResult.h</key> |
|||
<data> |
|||
oTrRd0HS6yuPr1JxLpx1Qgr6sKw= |
|||
</data> |
|||
<key>Info.plist</key> |
|||
<data> |
|||
yF0Q5ofGeBGl7TtNvUrICUVzXe8= |
|||
</data> |
|||
<key>Modules/module.modulemap</key> |
|||
<data> |
|||
VG59AHi+XKWb6IYCdGbZKHPgBbA= |
|||
</data> |
|||
</dict> |
|||
<key>files2</key> |
|||
<dict> |
|||
<key>Headers/JLBmpConvert.h</key> |
|||
<dict> |
|||
<key>hash</key> |
|||
<data> |
|||
5urDCSjpqHBbBhVbnkpZDUAqfUQ= |
|||
</data> |
|||
<key>hash2</key> |
|||
<data> |
|||
Ps103art4k9gGQecTWk7WrWV5o2nY38Acp7pydnv0oc= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLBmpConvertKit.h</key> |
|||
<dict> |
|||
<key>hash</key> |
|||
<data> |
|||
rJo680NKOdjmobcOdHzU3oQ05lQ= |
|||
</data> |
|||
<key>hash2</key> |
|||
<data> |
|||
9kChXiw3D4JFaLjgBlaq+/2FazTsVCbA3kfmrYQ+9/A= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLBmpConvertOption.h</key> |
|||
<dict> |
|||
<key>hash</key> |
|||
<data> |
|||
bPMnU/cb1ZNEvx+6wLH+tNggsWM= |
|||
</data> |
|||
<key>hash2</key> |
|||
<data> |
|||
4rgpTV2uvjOrNb0Bx7HOxoqBCtJjHaA7CcNBjIImXzY= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLGifBin.h</key> |
|||
<dict> |
|||
<key>hash</key> |
|||
<data> |
|||
+UKivjyP0JG0+mVZPKUAWwhParQ= |
|||
</data> |
|||
<key>hash2</key> |
|||
<data> |
|||
A8LhdAy5NiJx3J5nKUE53rzYmIKX6Cp9oTpGfJJk+tQ= |
|||
</data> |
|||
</dict> |
|||
<key>Headers/JLImageConvertResult.h</key> |
|||
<dict> |
|||
<key>hash</key> |
|||
<data> |
|||
oTrRd0HS6yuPr1JxLpx1Qgr6sKw= |
|||
</data> |
|||
<key>hash2</key> |
|||
<data> |
|||
vacF3oh76vh4n8lafP3hAi/fYXjU4YoqA6CbjC05MYw= |
|||
</data> |
|||
</dict> |
|||
<key>Modules/module.modulemap</key> |
|||
<dict> |
|||
<key>hash</key> |
|||
<data> |
|||
VG59AHi+XKWb6IYCdGbZKHPgBbA= |
|||
</data> |
|||
<key>hash2</key> |
|||
<data> |
|||
nU2jpsOghgGuDPwpIFZ+hGnZ5Xj24fG1pjw1H8vpwEs= |
|||
</data> |
|||
</dict> |
|||
</dict> |
|||
<key>rules</key> |
|||
<dict> |
|||
<key>^.*</key> |
|||
<true/> |
|||
<key>^.*\.lproj/</key> |
|||
<dict> |
|||
<key>optional</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1000</real> |
|||
</dict> |
|||
<key>^.*\.lproj/locversion.plist$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1100</real> |
|||
</dict> |
|||
<key>^Base\.lproj/</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>1010</real> |
|||
</dict> |
|||
<key>^version.plist$</key> |
|||
<true/> |
|||
</dict> |
|||
<key>rules2</key> |
|||
<dict> |
|||
<key>.*\.dSYM($|/)</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>11</real> |
|||
</dict> |
|||
<key>^(.*/)?\.DS_Store$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>2000</real> |
|||
</dict> |
|||
<key>^.*</key> |
|||
<true/> |
|||
<key>^.*\.lproj/</key> |
|||
<dict> |
|||
<key>optional</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1000</real> |
|||
</dict> |
|||
<key>^.*\.lproj/locversion.plist$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>1100</real> |
|||
</dict> |
|||
<key>^Base\.lproj/</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>1010</real> |
|||
</dict> |
|||
<key>^Info\.plist$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
<key>^PkgInfo$</key> |
|||
<dict> |
|||
<key>omit</key> |
|||
<true/> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
<key>^embedded\.provisionprofile$</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
<key>^version\.plist$</key> |
|||
<dict> |
|||
<key>weight</key> |
|||
<real>20</real> |
|||
</dict> |
|||
</dict> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1 @@ |
|||
Versions/Current/Headers |
|||
@ -0,0 +1 @@ |
|||
Versions/Current/JLBmpConvertKit |
|||
@ -0,0 +1 @@ |
|||
Versions/Current/Modules |
|||
@ -0,0 +1 @@ |
|||
Versions/Current/Resources |
|||
@ -0,0 +1,95 @@ |
|||
//
|
|||
// JLBmpCovert.h
|
|||
// JLBmpCovertKit
|
|||
//
|
|||
// Created by EzioChan on 2024/9/9.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLBmpConvertKit/JLBmpConvertKit.h> |
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
#import <UIKit/UIKit.h> |
|||
#elif TARGET_OS_OSX |
|||
#import <AppKit/AppKit.h> |
|||
#endif |
|||
|
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLImageConvertResult; |
|||
|
|||
typedef void(^JLBmpCovertCallBack)(NSString *inFilePath,NSString *__nullable outFilePath,NSError *__nullable error) __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
typedef void(^JLBmpCovertCallBack2)(NSData *__nullable outFileData,NSError *__nullable error) __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
|
|||
/// 图像转换
|
|||
@interface JLBmpConvert : NSObject |
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - type: 转换类型
|
|||
/// - inFilePath: 输入文件
|
|||
/// - outFilePath: 输出文件
|
|||
/// - completion: 回调
|
|||
+(void)covert:(JLBmpConvertType)type |
|||
inFilePath:(NSString *_Nonnull)inFilePath |
|||
outFilePath:(NSString * __nullable)outFilePath |
|||
completion:(JLBmpCovertCallBack _Nonnull)completion __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - type: 转换类型
|
|||
/// - inImage: 输入图片
|
|||
/// - completion: 回调
|
|||
+(void)covert:(JLBmpConvertType)type |
|||
Image:(UIImage *)inImage |
|||
completion:(JLBmpCovertCallBack2 _Nonnull)completion __deprecated_msg("This interface is deprecated. Please use convert:inFilePath:outFilePath: or convert:Image: instead."); |
|||
|
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - option: 类型
|
|||
/// 当前仅仅 707N 系列芯片可指定图像格式
|
|||
/// - inFilePath: 输入文件
|
|||
/// - outFilePath: 输出文件
|
|||
/// 文件路径转换入口
|
|||
+ (JLImageConvertResult *)convert:(JLBmpConvertOption *)option |
|||
inFilePath:(NSString *)inFilePath |
|||
outFilePath:(NSString * __nullable)outFilePath; |
|||
|
|||
/// UIImage 转换
|
|||
/// 当前仅仅 707N 系列芯片可指定图像格式
|
|||
/// - Parameters:
|
|||
/// - option: 类型
|
|||
/// - imgData: 图片的原始数据
|
|||
+(JLImageConvertResult *)convert:(JLBmpConvertOption *)option ImageData:(NSData *)imgData; |
|||
|
|||
|
|||
/// UIImage 转换成 BGRA
|
|||
/// - Parameter image: 图片
|
|||
+(NSData*)convertImageToBGRABytes:(UIImage *)image; |
|||
|
|||
/// UIImage 转换成 RGBA
|
|||
/// - Parameter image: 图片
|
|||
+(NSData*)convertImageToRGBABytes:(UIImage *)image; |
|||
|
|||
|
|||
/// 图片缩放
|
|||
/// - Parameters:
|
|||
/// - image: 图片
|
|||
/// - newSize: 缩放大小
|
|||
/// - Returns: 缩放后的图片
|
|||
+(NSData *)resizeImage:(UIImage*)image andResizeTo:(CGSize)newSize; |
|||
|
|||
#elif TARGET_OS_OSX |
|||
/// 图片转换
|
|||
/// - Parameters:
|
|||
/// - option: 转换类型
|
|||
/// - inImage: 输入图片
|
|||
+(JLImageConvertResult *)convert:(JLBmpConvertOption *)option Image:(NSImage *)image; |
|||
|
|||
#endif |
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,24 @@ |
|||
//
|
|||
// JLBmpConvertKit.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2024/9/9.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLBmpConvertKit.
|
|||
FOUNDATION_EXPORT double JLBmpConvertKitVersionNumber; |
|||
|
|||
//! Project version string for JLBmpConvertKit.
|
|||
FOUNDATION_EXPORT const unsigned char JLBmpConvertKitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLBmpConvertKit/PublicHeader.h>
|
|||
|
|||
|
|||
#import <JLBmpConvertKit/JLBmpConvertOption.h> |
|||
#import <JLBmpConvertKit/JLBmpConvert.h> |
|||
#import <JLBmpConvertKit/JLGifBin.h> |
|||
#import <JLBmpConvertKit/JLImageConvertResult.h> |
|||
|
|||
@ -0,0 +1,89 @@ |
|||
//
|
|||
// JLBmpConvertOption.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2025/5/23.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// 图像转换类型
|
|||
typedef NS_ENUM(NSUInteger, JLBmpConvertType) { |
|||
/// 695N 图像转换 RGB 转换成 695N 芯片对应的图像资源
|
|||
/// 对应原 BR23 转换算法
|
|||
JLBmpConvertType695N_RBG = 0, |
|||
/// 701N 图像转换 RGB 转换成 701N 芯片对应的图像资源
|
|||
/// 对应原 BR28 转换的算法
|
|||
JLBmpConvertType701N_RBG = 1, |
|||
/// 701N 图像转换 ARGB 转换成 701N 芯片对应的图像资源
|
|||
/// 对应原 BR28_ARBG 转换的算法
|
|||
JLBmpConvertType701N_ARBG = 2, |
|||
/// 701N 图像转换 RGB 转换成 701N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应原 BR28_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType701N_RBG_NO_PACK = 3, |
|||
/// 701N 图像转换 ARGB 转换成 701N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应原 BR28_ARGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType701N_ARGB_NO_PACK = 4, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源
|
|||
/// 对应 BR35 转换的算法
|
|||
JLBmpConvertType707N_RBG = 5, |
|||
/// 707N 图像转换 ARGB 转换成 707N 芯片对应的图像资源
|
|||
/// 对应 BR35_ARGB 转换的算法
|
|||
JLBmpConvertType707N_ARGB = 6, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应 BR35_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType707N_ARGB_NO_PACK = 7, |
|||
/// 707N 图像转换 RGB 转换成 707N 芯片对应的图像资源(不打包封装)
|
|||
/// 对应 BR35_RGB_NO_PACK 转换的算法(不打包封装)
|
|||
JLBmpConvertType707N_RBG_NO_PACK = 8, |
|||
/// 701N 图像转换 JPEG
|
|||
/// 仅仅支持 JPEG 类型
|
|||
JLBmpConvertType701N_JPEG = 9 |
|||
}; |
|||
|
|||
/// 图像格式
|
|||
/// 仅(707N 系列芯片支持)
|
|||
typedef NS_ENUM(NSUInteger, JLBmpPixelformat) { |
|||
/// ARBG8888/RBG888 格式
|
|||
JLBmpPixelformat_888, |
|||
/// ARBG8565/RBG565 格式
|
|||
JLBmpPixelformat_565, |
|||
/// 自动选择最小的格式
|
|||
JLBmpPixelformat_Auto, |
|||
}; |
|||
|
|||
/// LVGL 打包格式
|
|||
typedef NS_ENUM(NSUInteger, JLBmpPacketFormat) { |
|||
JLBmpPacketFormatNone = 0, |
|||
JLBmpPacketFormatJLUI = 1, |
|||
JLBmpPacketFormatLVGL = 2 |
|||
}; |
|||
|
|||
/// 图像转换选项
|
|||
@interface JLBmpConvertOption : NSObject |
|||
|
|||
/// 图像转换类型
|
|||
@property (nonatomic, assign) JLBmpConvertType convertType; |
|||
|
|||
/// 图像格式
|
|||
/// 默认为 auto
|
|||
/// 仅(707N 系列芯片支持)
|
|||
@property (nonatomic, assign) JLBmpPixelformat pixelformat; |
|||
|
|||
/// LVGL 打包格式
|
|||
/// 默认为 JLUI
|
|||
/// 仅(707N 系列芯片支持)
|
|||
@property (nonatomic, assign) JLBmpPacketFormat packetFormat; |
|||
|
|||
/// 是否转换成 BGRA
|
|||
/// 当使用的是 JL 的 UI 框架时需要使用
|
|||
/// 使用其他第三方框架时,需要根据固件端框架进行调整
|
|||
/// default YES
|
|||
@property (nonatomic, assign) BOOL convertToBGRA; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,77 @@ |
|||
//
|
|||
// JLGifBin.h
|
|||
// JLGifLib
|
|||
//
|
|||
// Created by EzioChan on 2024/1/18.
|
|||
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// Gif 转 Bin 支持的芯片类型
|
|||
typedef NS_ENUM(NSUInteger, JLGIFBinChipType) { |
|||
/// 701N
|
|||
JLGIFBinChipJL_701N, |
|||
/// 707N
|
|||
JLGIFBinChipJL_707N, |
|||
}; |
|||
|
|||
///packet 是否打包
|
|||
typedef NS_ENUM(NSInteger, JLGIFBinPackageType) { |
|||
/// 不做其他打包使用源数据,适用 LVGL 的公版UI框架
|
|||
JLGIFBinPackageTypeLVGL = 0, |
|||
/// 杰理打包格式,适用 JLVGL 的杰理定制版 UI 框架
|
|||
JLGIFBinPackageTypeJLVGL = 1, |
|||
}; |
|||
|
|||
typedef void(^JLGif2BinBlock)(int code,NSData *_Nullable binData); |
|||
|
|||
/// Gif 转 Bin
|
|||
@interface JLGifBin : NSObject |
|||
|
|||
/// 打印当前SDK的版本
|
|||
+(void)sdkVersion; |
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率
|
|||
/// 3: 高码率
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level Result:(JLGif2BinBlock)block __attribute__((deprecated("Use makeDataToBin:Level:ChipType:Result: instead."))); |
|||
|
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// 3: 高码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// - chip: 芯片类型
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level ChipType:(JLGIFBinChipType)chip Result:(JLGif2BinBlock)block __attribute__((deprecated("Use makeDataToBin:Level:ChipType:PackageType:Result: instead."))); |
|||
|
|||
|
|||
/// 根据 Gif 创建 Bin
|
|||
/// - Parameters:
|
|||
/// - gifData: Gif 图片数据
|
|||
/// - level: 等级
|
|||
/// 1: 低码率
|
|||
/// 2: 中码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// 3: 高码率 (仅 JLGIFBinChipJL_701N 支持)
|
|||
/// - chip: 芯片类型
|
|||
/// - packageType: 打包类型
|
|||
/// 1: JLUI 杰理 UI 格式
|
|||
/// 0: 无 不打包
|
|||
/// - block: 回调内容
|
|||
+(void)makeDataToBin:(NSData *)gifData Level:(int)level ChipType:(JLGIFBinChipType)chip PackageType:(JLGIFBinPackageType)packageType Result:(JLGif2BinBlock)block; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,34 @@ |
|||
//
|
|||
// JLImageConvertResult.h
|
|||
// JLBmpConvertKit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/6.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/// 图像转换结果
|
|||
@interface JLImageConvertResult : NSObject |
|||
/// 结果码
|
|||
@property (nonatomic, assign) int result; |
|||
/// 数据大小
|
|||
@property (nonatomic, assign) int buf_size; |
|||
/// 图像格式
|
|||
@property (nonatomic, assign) int pixel_format; |
|||
/// 压缩模式
|
|||
@property (nonatomic, assign) int compress_mode; |
|||
|
|||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST |
|||
/// 输出文件路径
|
|||
@property (nullable, nonatomic, copy) NSString *outFilePath; |
|||
#endif |
|||
|
|||
/// 输出文件内容
|
|||
@property (nullable, nonatomic, copy) NSData *outFileData; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
framework module JLBmpConvertKit { |
|||
umbrella header "JLBmpConvertKit.h" |
|||
export * |
|||
|
|||
module * { export * } |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>BuildMachineOSBuild</key> |
|||
<string>25B78</string> |
|||
<key>CFBundleDevelopmentRegion</key> |
|||
<string>en</string> |
|||
<key>CFBundleExecutable</key> |
|||
<string>JLBmpConvertKit</string> |
|||
<key>CFBundleIdentifier</key> |
|||
<string>com.zh-jieli.JLBmpConvertKit</string> |
|||
<key>CFBundleInfoDictionaryVersion</key> |
|||
<string>6.0</string> |
|||
<key>CFBundleName</key> |
|||
<string>JLBmpConvertKit</string> |
|||
<key>CFBundlePackageType</key> |
|||
<string>FMWK</string> |
|||
<key>CFBundleShortVersionString</key> |
|||
<string>1.5.0</string> |
|||
<key>CFBundleSupportedPlatforms</key> |
|||
<array> |
|||
<string>MacOSX</string> |
|||
</array> |
|||
<key>CFBundleVersion</key> |
|||
<string>1</string> |
|||
<key>DTCompiler</key> |
|||
<string>com.apple.compilers.llvm.clang.1_0</string> |
|||
<key>DTPlatformBuild</key> |
|||
<string>25C57</string> |
|||
<key>DTPlatformName</key> |
|||
<string>macosx</string> |
|||
<key>DTPlatformVersion</key> |
|||
<string>26.2</string> |
|||
<key>DTSDKBuild</key> |
|||
<string>25C57</string> |
|||
<key>DTSDKName</key> |
|||
<string>macosx26.2</string> |
|||
<key>DTXcode</key> |
|||
<string>2620</string> |
|||
<key>DTXcodeBuild</key> |
|||
<string>17C52</string> |
|||
<key>LSMinimumSystemVersion</key> |
|||
<string>10.13</string> |
|||
<key>NSHumanReadableCopyright</key> |
|||
<string>Copyright © 2024 www.zh-jieli.com. All rights reserved.</string> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1 @@ |
|||
A |
|||
@ -0,0 +1,44 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>AvailableLibraries</key> |
|||
<array> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLDialUnit.framework/JLDialUnit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>ios-arm64</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLDialUnit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>arm64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>ios</string> |
|||
</dict> |
|||
<dict> |
|||
<key>BinaryPath</key> |
|||
<string>JLDialUnit.framework/JLDialUnit</string> |
|||
<key>LibraryIdentifier</key> |
|||
<string>ios-arm64_x86_64-simulator</string> |
|||
<key>LibraryPath</key> |
|||
<string>JLDialUnit.framework</string> |
|||
<key>SupportedArchitectures</key> |
|||
<array> |
|||
<string>arm64</string> |
|||
<string>x86_64</string> |
|||
</array> |
|||
<key>SupportedPlatform</key> |
|||
<string>ios</string> |
|||
<key>SupportedPlatformVariant</key> |
|||
<string>simulator</string> |
|||
</dict> |
|||
</array> |
|||
<key>CFBundlePackageType</key> |
|||
<string>XFWK</string> |
|||
<key>XCFrameworkFormatVersion</key> |
|||
<string>1.0</string> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1,127 @@ |
|||
//
|
|||
// DialManager.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by 杰理科技 on 2021/7/20.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLDialUnit/FatfsObject.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
|
|||
|
|||
typedef NS_ENUM(NSInteger, DialOperateType) { |
|||
DialOperateTypeNoSpace = 0, //空间不足
|
|||
DialOperateTypeDoing = 1, //正在操作
|
|||
DialOperateTypeFail = 2, //操作失败
|
|||
DialOperateTypeSuccess = 3, //操作成功
|
|||
DialOperateTypeUnnecessary = 4, //无需重复打开文件系统
|
|||
DialOperateTypeResetFial = 5, //重置文件系统失败
|
|||
DialOperateTypeNormal = 6, //文件系统正常
|
|||
DialOperateTypeCmdFail = 7, //流程命令执行失败
|
|||
}; |
|||
typedef NS_ENUM(NSInteger, DialUpdateResult) { |
|||
DialUpdateResultFinished = 0, //更新资源完成
|
|||
DialUpdateResultNewest = 1, //资源已最新
|
|||
DialUpdateResultInvalid = 2, //资源无效
|
|||
DialUpdateResultEmpty = 3, //资源为空
|
|||
DialUpdateResultReplace = 4, //资源替换
|
|||
DialUpdateResultAdd = 5, //资源新增
|
|||
DialUpdateResultNoSpace = 6, //空间不足
|
|||
DialUpdateResultZipError = 7, //ZIP资源文件错误
|
|||
DialUpdateResultCompareFail = 8, //表盘资源对比失败
|
|||
DialUpdateResultUpdateUfw = 9, //更新固件 ufw
|
|||
}; |
|||
typedef void(^DialOperateBK)(DialOperateType type, float progress); |
|||
typedef void(^DialListBK)(DialOperateType type, NSArray* __nullable array); |
|||
typedef void(^DialUpdateBK)(DialUpdateResult updateResult, |
|||
NSArray* __nullable array, |
|||
NSString * _Nullable filePath, |
|||
NSInteger index ,float progress); |
|||
|
|||
typedef void(^FatfsFreeBlock)(uint32_t freeSize); |
|||
|
|||
/// 表盘管理类
|
|||
@interface DialManager : NSObject |
|||
|
|||
#pragma mark - 连接成功后,必须调用一次! |
|||
+(void)openDialFileSystemWithCmdManager:(JL_ManagerM *)manager withResult:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 重置表盘系统 |
|||
+(void)resetDialFileSystemWithCmdManager:(JL_ManagerM *)manager withResult:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 查询文件 |
|||
/// 查询文件
|
|||
/// @param result 操作回调
|
|||
+(void)listFile:(DialListBK __nullable)result; |
|||
|
|||
#pragma mark - 添加文件 |
|||
/// 添加文件
|
|||
/// @param file 文件名需要加斜杠,类似@“/WACTH1”。
|
|||
/// @param content 文件数据
|
|||
/// @param result 操作回调
|
|||
+(void)addFile:(NSString*)file |
|||
Content:(NSData*)content |
|||
Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 删除文件 |
|||
/// 删除文件(第一种)
|
|||
/// @param file 文件名需要加斜杠,类似@“/WACTH1”。
|
|||
/// @param result 操作回调
|
|||
+(void)deleteFile:(NSString*)file |
|||
Result:(DialOperateBK)result; |
|||
|
|||
/// 删除文件(第二种)
|
|||
/// @param fileModel JLModel_File类型
|
|||
/// @param result 操作回调
|
|||
+(void)deleteDialResourceWithFileModel:(JLModel_File*)fileModel Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 替换文件 |
|||
/// 替换文件
|
|||
/// @param file 文件名需要加斜杠,类似@“/WACTH1”。
|
|||
/// @param content 文件数据
|
|||
/// @param result 操作回调
|
|||
+(void)repaceFile:(NSString*)file |
|||
Content:(NSData*)content |
|||
Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 格式化外部Flash |
|||
/// 格式化外部Flash操作
|
|||
/// @param handle 设备句柄
|
|||
/// @param result 操作回调
|
|||
+(void)formatFlash:(NSString*)handle Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 更新设备的表盘资源(异步调用) |
|||
/// 更新设备的表盘资源(异步调用)
|
|||
/// @param path 资源文件
|
|||
/// @param array 表盘列表(当前)
|
|||
/// @param result 更新结果
|
|||
+(void)updateResourcePath:(NSString*)path |
|||
List:(NSArray*)array |
|||
Result:(DialUpdateBK)result; |
|||
|
|||
/// 获取 fatfs 系统的剩余空间(仅仅fatfs 系统可用)
|
|||
/// 需要异步执行
|
|||
+(uint32_t)getFatfsFree; |
|||
|
|||
/// 获取 fatfs 系统的剩余空间(仅仅fatfs 系统可用)
|
|||
/// @param block 回调空间
|
|||
+(void)getFatfsFree:(FatfsFreeBlock) block; |
|||
|
|||
/// 获取某文件的文件大小
|
|||
/// @param fileName 文件名
|
|||
+(uint32_t)getSizeOfFileName:(NSString*)fileName; |
|||
|
|||
|
|||
/// 记录文件大小(私有接口)
|
|||
/// @param size 文件大小
|
|||
/// @param fileName 文件名
|
|||
+(void)setFileSize:(uint32_t)size FileName:(NSString*)fileName; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,92 @@ |
|||
//
|
|||
// FatfsObject.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by 杰理科技 on 2021/7/20.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
|
|||
|
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
@interface FatfsObject : NSObject |
|||
|
|||
#pragma mark ---> FATFS API |
|||
/// 输入命令中心类,在JL_Entity内。
|
|||
/// @param manager 命令中心类
|
|||
+(void)makeCmdManager:(JL_ManagerM*)manager; |
|||
|
|||
/// 返回 当前 JL_ManagerM
|
|||
+(JL_ManagerM*)outputCmdManager; |
|||
|
|||
/// 设置外挂Flash的大小,FATFS的大小。
|
|||
/// @param flashSize Flash大小
|
|||
/// @param fatsSize FATFS的大小
|
|||
+(BOOL)makeFlashSize:(uint32_t)flashSize |
|||
FatsSize:(uint32_t)fatsSize; |
|||
|
|||
/// 获取Flash上的文件
|
|||
/// @param path 文件名数组,其中"JL",“FONT”不能操作。
|
|||
+(NSArray*)makeListPath:(NSString*)path; |
|||
|
|||
typedef void(^FatfsCreateFile_BK)(float progress); |
|||
/// 新增文件
|
|||
/// @param path “/文件名”
|
|||
/// @param data 文件数据内容
|
|||
/// @param result 进度
|
|||
+(BOOL)makeCreateFile:(NSString*)path |
|||
Content:(NSData* __nullable)data |
|||
Result:(FatfsCreateFile_BK __nullable)result; |
|||
|
|||
typedef void(^FatfsReplaceFile_BK)(float progress); |
|||
/// 替换文件
|
|||
/// @param path “/文件名”
|
|||
/// @param data 文件数据内容
|
|||
+(BOOL)makeReplaceFile:(NSString*)path |
|||
Content:(NSData* __nullable)data |
|||
Result:(FatfsReplaceFile_BK __nullable)result; |
|||
|
|||
/// 删除文件
|
|||
/// @param path “/文件名”
|
|||
+(BOOL)makeRemoveFile:(NSString*)path; |
|||
|
|||
/*---------------------------------------------------------------------------------
|
|||
FatSize -- FAT文件系统认为自己的大小 |
|||
因为小机的FAT项按4K对齐了大小,所以实际上会认为FAT系统占用的空间比FLASH实际大小还要大 |
|||
用 f_getfree 获取的是 FAT文件系统认为自己剩余的空间的簇个数,其中有一部分是在Flash上实际不存在的 |
|||
所以需要减掉这部分 |
|||
计算方式如下: |
|||
FatUsed = FatSize - FreeSize |
|||
FlashRemainSize = FlashSize - FatUsed |
|||
----------------------------------------------------------------------------------*/ |
|||
/// 获取FATFS系统剩余空间,“FreeSize”。
|
|||
+(uint32_t)makeGetFree; |
|||
|
|||
/// 查看watch本间版本
|
|||
/// @param path 文件路径
|
|||
+(NSString*)makeVersionWatch:(NSString*)path; |
|||
|
|||
/// 获取文件前面512个字节
|
|||
/// @param path 文件路径
|
|||
+(NSData *)makeFileHead:(NSString*)path; |
|||
|
|||
/// 读文件
|
|||
/// @param path 文件路径
|
|||
+(NSData*)makeFileContent:(NSString*)path; |
|||
|
|||
/// 解压资源文件
|
|||
/// @param path 文件路径
|
|||
/// @param aimDirection 存放的路径
|
|||
+(NSArray*)unzipFileAtPath:(NSString *)path toDestination:(NSString *)aimDirection; |
|||
|
|||
/// 重置外部flash
|
|||
+(BOOL)makeResetFlash; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
|
|||
@ -0,0 +1,27 @@ |
|||
//
|
|||
// JLDialSourceModel.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/19.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
@interface JLDialSourceModel : JLModel_File |
|||
|
|||
/// 文件大小
|
|||
@property (nonatomic, assign)int size; |
|||
|
|||
/// CRC
|
|||
@property (nonatomic, assign)uint16_t crc; |
|||
|
|||
+(JLDialSourceModel *)createModel:(JLModel_File *)model; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,30 @@ |
|||
//
|
|||
// JLDialUnit.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2023/2/28.
|
|||
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLDialUnit.
|
|||
FOUNDATION_EXPORT double JLDialUnitVersionNumber; |
|||
|
|||
//! Project version string for JLDialUnit.
|
|||
FOUNDATION_EXPORT const unsigned char JLDialUnitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLDialUnit/PublicHeader.h>
|
|||
|
|||
#import <JLDialUnit/DialManager.h> |
|||
#import <JLDialUnit/FatfsObject.h> |
|||
#import <JLDialUnit/ZipZap.h> |
|||
#import <JLDialUnit/ZZArchive.h> |
|||
#import <JLDialUnit/ZZArchiveEntry.h> |
|||
#import <JLDialUnit/ZZConstants.h> |
|||
#import <JLDialUnit/ZZError.h> |
|||
#import <JLDialUnit/JLDialSourceModel.h> |
|||
#import <JLDialUnit/JLDialUnitMgr.h> |
|||
#import <JLDialUnit/JLSourceUpdate.h> |
|||
|
|||
|
|||
@ -0,0 +1,115 @@ |
|||
//
|
|||
// JLDialUnitMgr.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/18.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_HashPair/JL_HashPair.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLDialSourceModel; |
|||
@interface JLDialUnitMgr : NSObject |
|||
|
|||
/// 设备文件列表
|
|||
@property (nonatomic,strong)NSMutableArray <JLDialSourceModel *> *fileArray; |
|||
|
|||
/// 当前 Flash 操控句柄
|
|||
@property (nonatomic, strong) JLFlashOpMgr *currentFlaghOpMgr; |
|||
|
|||
/// 当前使用的表盘文件
|
|||
@property (nonatomic,strong)JLDialSourceModel *currentFileSource; |
|||
|
|||
/// 当前使用的表盘背景
|
|||
@property (nonatomic,strong)JLDialSourceModel *_Nullable currentBackground; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - mgr: 蓝牙管理对象
|
|||
/// - completion: 回调
|
|||
-(instancetype)initWithManager:(JL_ManagerM*)mgr completion:(void (^)(NSError * _Nullable))completion; |
|||
|
|||
/// 获取文件列表
|
|||
/// - Parameters:
|
|||
/// - cardType: 设备存储的类型
|
|||
/// - count: 请求的数目
|
|||
/// - completion: 回调
|
|||
/// 返回时,是返回累计数目
|
|||
-(void)getFileList:(JL_CardType)cardType count:(NSInteger)count completion:(void (^)(NSArray <JLDialSourceModel *> * _Nullable,NSError * _Nullable))completion; |
|||
|
|||
/// 清空文件列表
|
|||
/// - Parameter cardType: 设备存储的类型
|
|||
-(void)cleanFileList; |
|||
|
|||
/// 更新文件列表信息
|
|||
/// - Parameters:
|
|||
/// - fileSources: NSArray<JLModel_File *>
|
|||
/// - completion: 回调
|
|||
-(void)updateFileSources:(NSArray<JLModel_File *> *)fileSources completion:(void (^)(NSArray<JLDialSourceModel *> * _Nullable,NSError * _Nullable))completion; |
|||
|
|||
/// 更新文件到设备
|
|||
/// - Parameters:
|
|||
/// - fileHandleType: 设备目标存储句柄
|
|||
/// - fileData: 文件数据
|
|||
/// - filePath: 文件存储路径
|
|||
/// - resultCompletion: 回调
|
|||
/// state: 0:成功 1:传输中 -1:失败
|
|||
/// progress: 传输进度
|
|||
/// error: 错误
|
|||
-(void)updateFileToDevice:(JL_FileHandleType)fileHandleType Data:(NSData *)fileData FilePath:(NSString *)filePath completion:(void (^)(int,double,NSError * _Nullable))resultCompletion; |
|||
|
|||
/// 删除文件
|
|||
/// - Parameters:
|
|||
/// - filePath: 文件路径
|
|||
/// - resultCompletion: 回调
|
|||
-(void)deleteFile:(NSString *)filePath getFileList:(BOOL)isGet Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 删除多个文件
|
|||
/// - Parameters:
|
|||
/// - filePathList: 文件路径
|
|||
/// - resultCompletion: 回调
|
|||
-(void)deleteFiles:(NSArray <NSString*>*) filePathList Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 获取剩余空间
|
|||
/// - Parameter completion: 回调
|
|||
-(void)getRemainingSpace:(void(^)(int freeSize, NSError * _Nullable error))completion; |
|||
|
|||
/// 获取剩余空间 V1
|
|||
/// - Parameter completion: 回调
|
|||
-(void)getFlashRemainingSpace:(void(^)(int freeSize, NSError * _Nullable error))completion; |
|||
|
|||
//MARK: 表盘操作
|
|||
|
|||
/// 获取当前正在使用的表盘
|
|||
/// - Parameter completion: 回调
|
|||
-(void)dialGetCurrent:(void (^)(JLDialSourceModel * _Nullable))completion; |
|||
|
|||
/// 设置当前表盘
|
|||
/// - Parameters:
|
|||
/// - model: 表盘
|
|||
/// - resultCompletion: 回调
|
|||
-(void)dialSetCurrent:(JLDialSourceModel *)model Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 激活自定义表盘背景
|
|||
/// - Parameters:
|
|||
/// - model: 表盘背景对象
|
|||
/// - resultCompletion: 回调
|
|||
-(void)dialActiveCustomBackground:(JLDialSourceModel *)model Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 重置自定义表盘背景
|
|||
/// - Parameter resultCompletion: 回调
|
|||
-(void)dialResetCustomBackground:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 获取表盘背景
|
|||
/// - Parameters:
|
|||
/// - path: 路径 诸如“/WATCH”
|
|||
/// - resultCompletion: 回调
|
|||
-(void)dialGetDial:(NSString *)path BackgroundInfo:(void (^)(JLDialSourceModel * _Nullable model, NSError * _Nullable error))resultCompletion; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,94 @@ |
|||
//
|
|||
// JLSourceUpdate.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/18.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLDialUnitMgr; |
|||
|
|||
typedef NS_ENUM(NSInteger, JLSourceUpdateType) { |
|||
/// 更新资源完成
|
|||
JLSourceUpdateTypeFinished = 0, |
|||
/// 资源已最新
|
|||
JLSourceUpdateTypeNewest = 1, |
|||
/// 资源无效
|
|||
JLSourceUpdateTypeInvalid = 2, |
|||
/// 资源为空
|
|||
JLSourceUpdateTypeEmpty = 3, |
|||
/// 资源更新错误
|
|||
JLSourceUpdateTypeSrcError = 4, |
|||
/// 资源更新中
|
|||
JLSourceUpdateTypeUpdateing = 5, |
|||
/// 空间不足
|
|||
JLSourceUpdateTypeNoSpace = 6, |
|||
/// ZIP 资源文件错误
|
|||
JLSourceUpdateTypeZipError = 7, |
|||
/// 表盘资源对比失败
|
|||
JLSourceUpdateTypeCompareFail = 8, |
|||
/// 更新固件 ufw
|
|||
JLSourceUpdateTypeUpdateUfw = 9, |
|||
/// 不支持
|
|||
JLSourceUpdateTypeUpdateNotSupport = 10, |
|||
}; |
|||
|
|||
|
|||
@interface JLSourceInfo : NSObject |
|||
|
|||
@property(nonatomic,strong)NSString *filePath; |
|||
@property(nonatomic,strong,readonly)NSData * _Nullable fileData; |
|||
@property(nonatomic,strong,readonly)NSString *fileName; |
|||
@property(nonatomic,assign)NSInteger index; |
|||
|
|||
@end |
|||
|
|||
@protocol JLSourceUpdateDelegate <NSObject> |
|||
|
|||
- (void)updateProgress:(double)progress type:(JLSourceUpdateType)type source:(JLSourceInfo *_Nullable)source error:(NSError* _Nullable)error; |
|||
|
|||
- (void)updateUfwFirst:(NSString *)filePath ThenUpdateSrc:(NSArray <JLSourceInfo *>*) filePaths; |
|||
|
|||
@end |
|||
|
|||
/// 资源更新
|
|||
@interface JLSourceUpdate : NSObject |
|||
|
|||
@property(nonatomic,weak)id<JLSourceUpdateDelegate> delegate; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - mgr: 蓝牙管理对象
|
|||
/// - fileType: 文件句柄
|
|||
/// - dialMgr: JLDialUnitMgr
|
|||
/// - delegate: 代理
|
|||
-(instancetype)initWithManager:(JL_ManagerM*)mgr HandleType:(JL_FileHandleType) fileType DialMgr:(JLDialUnitMgr *)dialMgr delegate:(id<JLSourceUpdateDelegate>)delegate; |
|||
|
|||
|
|||
/// 更新资源
|
|||
/// - Parameters:
|
|||
/// - path: zip包路径
|
|||
/// - mgr: JLDialUnitMgr
|
|||
-(void)updateSources:(NSString*)path DialUnitMgr:(JLDialUnitMgr *)mgr; |
|||
|
|||
|
|||
/// 更新资源 AC707N 手表特殊升级流程
|
|||
/// - Parameters:
|
|||
/// - path: zip 包路径
|
|||
/// - mgr: JLDialUnitMgr
|
|||
-(void)updateSourcesV2:(NSString*)path DialUnitMgr:(JLDialUnitMgr *)mgr; |
|||
|
|||
|
|||
/// 更新资源任务
|
|||
/// @param targetUpdateList 需要更新的文件列表
|
|||
/// @param updateResult 更新结果
|
|||
-(void)updateAciton:(NSArray *)targetUpdateList Result:(void (^)(BOOL isFinish, NSError * _Nullable))updateResult; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,131 @@ |
|||
//
|
|||
// ZZArchive.h
|
|||
// ZipZap
|
|||
//
|
|||
// Created by Glen Low on 25/09/12.
|
|||
// Copyright (c) 2012, Pixelglow Software. All rights reserved.
|
|||
//
|
|||
|
|||
//
|
|||
// Redistribution and use in source and binary forms, with or without modification,
|
|||
// are permitted provided that the following conditions are met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright notice,
|
|||
// this list of conditions and the following disclaimer.
|
|||
//
|
|||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|||
// this list of conditions and the following disclaimer in the documentation
|
|||
// and/or other materials provided with the distribution.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|||
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|||
// THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import "ZZConstants.h" |
|||
|
|||
@class ZZArchiveEntry; |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/**
|
|||
* The ZZArchive class represents a zip file for reading only. |
|||
*/ |
|||
@interface ZZArchive : NSObject |
|||
|
|||
/**
|
|||
* The URL representing this archive. |
|||
*/ |
|||
@property (readonly, nullable, nonatomic) NSURL* URL; |
|||
|
|||
/**
|
|||
* The uninterpreted contents of this archive. |
|||
*/ |
|||
@property (readonly, nonatomic) NSData* contents; |
|||
|
|||
/**
|
|||
* The array of ZZArchiveEntry entries within this archive. |
|||
*/ |
|||
@property (readonly, nonatomic) NSArray<ZZArchiveEntry*>* entries; |
|||
|
|||
/**
|
|||
* Creates a new archive with the zip file at the given file URL. |
|||
* |
|||
* The archive will use UTF-8 encoding for reading entry file names and comments, and will not create the file if it is missing. |
|||
* |
|||
* @param URL The file URL of the zip file. |
|||
* @param error The error information when an error occurs. Pass in nil if you do not want error information. |
|||
* @return The initialized archive. Returns nil if the archive cannot be initialized. |
|||
*/ |
|||
+ (nullable instancetype)archiveWithURL:(NSURL*)URL |
|||
error:(out NSError**)error; |
|||
|
|||
/**
|
|||
* Creates a new archive with the raw zip file data given. |
|||
* |
|||
* The archive will use UTF-8 encoding for reading entry file names and comments, and will not create the data if it is missing. |
|||
* |
|||
* @param data The raw data of the zip file. |
|||
* @param error The error information when an error occurs. Pass in nil if you do not want error information. |
|||
* @return The initialized archive. Returns nil if the archive cannot be initialized. |
|||
*/ |
|||
+ (nullable instancetype)archiveWithData:(NSData*)data |
|||
error:(out NSError**)error; |
|||
|
|||
/**
|
|||
* This initializer should never be used. |
|||
*/ |
|||
- (instancetype)init NS_UNAVAILABLE; |
|||
|
|||
/**
|
|||
* Initializes a new archive with the zip file at the given file URL. |
|||
* |
|||
* @param URL The file URL of the zip file. |
|||
* @param options The options to consider when opening the zip file. |
|||
* @param error The error information when an error occurs. Pass in nil if you do not want error information. |
|||
* @return The initialized archive. Returns nil if the archive cannot be initialized. |
|||
*/ |
|||
- (nullable instancetype)initWithURL:(NSURL*)URL |
|||
options:(nullable NSDictionary*)options |
|||
error:(out NSError**)error; |
|||
|
|||
/**
|
|||
* Initializes a new archive with the raw zip file data given. |
|||
* |
|||
* @param data The raw data of the zip file |
|||
* @param options The options to consider when opening the zip file. |
|||
* @param error The error information when an error occurs. Pass in nil if you do not want error information. |
|||
* @return The initialized archive. Returns nil if the archive cannot be initialized. |
|||
*/ |
|||
- (nullable instancetype)initWithData:(NSData*)data |
|||
options:(nullable NSDictionary*)options |
|||
error:(out NSError**)error; |
|||
|
|||
/**
|
|||
* Updates the entries and writes them to the source. |
|||
* |
|||
* If the write fails and the entries are completely new, the existing zip file will be untouched. |
|||
* |
|||
* If the write fails and the entries contain some or all existing entries, the zip file may be corrupted. |
|||
* In this case, the error information will report the ZZReplaceWriteErrorCode error code. |
|||
* |
|||
* @param newEntries The entries to update to, may contain some or all existing entries. |
|||
* @param error The error information when an error occurs. Pass in nil if you do not want error information. |
|||
* @return Whether the update was successful or not. |
|||
* |
|||
*/ |
|||
- (BOOL)updateEntries:(NSArray<ZZArchiveEntry*>*)newEntries |
|||
error:(out NSError**)error; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,239 @@ |
|||
//
|
|||
// ZZArchiveEntry.h
|
|||
// ZipZap
|
|||
//
|
|||
// Created by Glen Low on 25/09/12.
|
|||
// Copyright (c) 2012, Pixelglow Software. All rights reserved.
|
|||
//
|
|||
|
|||
//
|
|||
// Redistribution and use in source and binary forms, with or without modification,
|
|||
// are permitted provided that the following conditions are met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright notice,
|
|||
// this list of conditions and the following disclaimer.
|
|||
//
|
|||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|||
// this list of conditions and the following disclaimer in the documentation
|
|||
// and/or other materials provided with the distribution.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|||
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|||
// THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
|||
|
|||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) |
|||
#include <CoreGraphics/CoreGraphics.h> |
|||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) |
|||
#include <ApplicationServices/ApplicationServices.h> |
|||
#endif |
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
@protocol ZZArchiveEntryWriter; |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
/**
|
|||
* The ZZArchiveEntry class represents an entry in the ZZArchive instance. |
|||
*/ |
|||
@interface ZZArchiveEntry : NSObject |
|||
|
|||
/**
|
|||
* Whether the entry is compressed. |
|||
*/ |
|||
@property (readonly, nonatomic) BOOL compressed; |
|||
|
|||
/**
|
|||
* Whether the entry is encrypted. |
|||
*/ |
|||
@property (readonly, nonatomic) BOOL encrypted; |
|||
|
|||
/**
|
|||
* The last modified date and time of the entry. The time value is only accurate to 2 seconds. |
|||
*/ |
|||
@property (readonly, nonatomic) NSDate* lastModified; |
|||
|
|||
/**
|
|||
* The CRC32 code of the entry file: 0 for new entries. |
|||
*/ |
|||
@property (readonly, nonatomic) NSUInteger crc32; |
|||
|
|||
/**
|
|||
* The compressed size of the entry file: 0 for new entries. |
|||
*/ |
|||
@property (readonly, nonatomic) NSUInteger compressedSize; |
|||
|
|||
/**
|
|||
* The uncompressed size of the entry file: 0 for new entries. |
|||
*/ |
|||
@property (readonly, nonatomic) NSUInteger uncompressedSize; |
|||
|
|||
/**
|
|||
* The UNIX file mode for the entry: 0 for new or non-UNIX entries. This includes the file type bits. |
|||
*/ |
|||
@property (readonly, nonatomic) mode_t fileMode; |
|||
|
|||
/**
|
|||
* The file name of the entry. Encoding is either CP-437 or UTF-8, depending on the EFS flag of the general purpose bit flags. |
|||
*/ |
|||
@property (readonly, nonatomic) NSString* fileName; |
|||
|
|||
/**
|
|||
* The file name of the entry as array of bytes |
|||
*/ |
|||
@property (readonly, nonatomic) NSData* rawFileName; |
|||
|
|||
/**
|
|||
* The encoding of filename and comment fields, according to the EFS flag of the general purpose bit flags. |
|||
*/ |
|||
@property (readonly, nonatomic) NSStringEncoding encoding; |
|||
|
|||
/**
|
|||
* Creates a new file entry from a streaming callback. |
|||
* |
|||
* @param fileName The file name for the entry. |
|||
* @param compress Whether to compress the entry. |
|||
* @param streamBlock The callback to write the entry's data to the stream. Returns whether the write should be considered successful. |
|||
* @return The created entry. |
|||
*/ |
|||
+ (instancetype)archiveEntryWithFileName:(NSString*)fileName |
|||
compress:(BOOL)compress |
|||
streamBlock:(BOOL(^)(NSOutputStream* stream, NSError** error))streamBlock; |
|||
|
|||
/**
|
|||
* Creates a new file entry from a data callback. |
|||
* |
|||
* @param fileName The file name for the entry. |
|||
* @param compress Whether to compress the entry. |
|||
* @param dataBlock The callback to return the entry's data. Returns nil if the write should be considered unsuccessful. |
|||
* @return The created entry. |
|||
*/ |
|||
+ (instancetype)archiveEntryWithFileName:(NSString*)fileName |
|||
compress:(BOOL)compress |
|||
dataBlock:(NSData* _Nullable(^)(NSError** error))dataBlock; |
|||
|
|||
/**
|
|||
* Creates a new file entry from a data-consuming callback. |
|||
* |
|||
* @param fileName The file name for the entry. |
|||
* @param compress Whether to compress the entry. |
|||
* @param dataConsumerBlock The callback to put the entry's data into the data consumer. Returns whether the write should be considered successful. |
|||
* @return The created entry. |
|||
*/ |
|||
+ (instancetype)archiveEntryWithFileName:(NSString*)fileName |
|||
compress:(BOOL)compress |
|||
dataConsumerBlock:(BOOL(^)(CGDataConsumerRef dataConsumer, NSError** error))dataConsumerBlock; |
|||
|
|||
/**
|
|||
* Creates a new directory entry. |
|||
* |
|||
* @param directoryName The directory name for the entry. |
|||
* @return The created entry. |
|||
*/ |
|||
+ (instancetype)archiveEntryWithDirectoryName:(NSString*)directoryName; |
|||
|
|||
/**
|
|||
* Creates a new entry. |
|||
* |
|||
* The archive entry will choose the first non-nil dataBlock, streamBlock or dataConsumerBlock to supply its data. |
|||
* |
|||
* @param fileName The file name for the entry. |
|||
* @param fileMode The UNIX file mode for the entry. This includes the file type bits. |
|||
* @param lastModified The last modified date and time for the entry. The time value is only accurate to 2 seconds. |
|||
* @param compressionLevel The compression level for the entry: 0 for stored, -1 for default deflate, 1 - 9 for custom deflate levels. |
|||
* @param dataBlock The callback that returns the entry file data. Returns nil if the write should be considered unsuccessful. |
|||
* @param streamBlock The callback that writes the entry file to the stream. Returns whether the write should be considered successful. |
|||
* @param dataConsumerBlock The callback that writes the entry file to the data consumer. Returns whether the write should be considered successful. |
|||
* @return The created entry. |
|||
*/ |
|||
+ (instancetype)archiveEntryWithFileName:(NSString*)fileName |
|||
fileMode:(mode_t)fileMode |
|||
lastModified:(NSDate*)lastModified |
|||
compressionLevel:(NSInteger)compressionLevel |
|||
dataBlock:(nullable NSData* _Nullable(^)(NSError** error))dataBlock |
|||
streamBlock:(nullable BOOL(^)(NSOutputStream* stream, NSError** error))streamBlock |
|||
dataConsumerBlock:(nullable BOOL(^)(CGDataConsumerRef dataConsumer, NSError** error))dataConsumerBlock; |
|||
|
|||
/**
|
|||
* Checks whether the entry file is consistent. |
|||
* |
|||
* Checks whether the local file entry is consistent with the central file entry and also that |
|||
* the recorded and actual checksums of the data agree. |
|||
* |
|||
* @param error The error information when an error occurs. Pass in nil if you do not want error information. |
|||
* @return Whether entry file is consistent or not. |
|||
*/ |
|||
- (BOOL)check:(out NSError**)error; |
|||
|
|||
/**
|
|||
* The file name of the entry with the given encoding. |
|||
* |
|||
* @param encoding The encoding for the filename. |
|||
*/ |
|||
- (NSString*)fileNameWithEncoding:(NSStringEncoding)encoding; |
|||
|
|||
/**
|
|||
* Creates a stream to represent the entry file. |
|||
* |
|||
* @param error A pointer to a variable that will contain the error if any. |
|||
* @return The new stream: nil for new entries. |
|||
*/ |
|||
- (nullable NSInputStream*)newStreamWithError:(NSError**)error; |
|||
|
|||
/**
|
|||
* Creates a stream to represent the entry file. |
|||
* |
|||
* @param password The password to be used for decryption. |
|||
* @param error A pointer to a variable that will contain the error if any. |
|||
* @return The new stream: nil for new entries. |
|||
*/ |
|||
- (nullable NSInputStream*)newStreamWithPassword:(nullable NSString*)password error:(NSError**)error; |
|||
|
|||
/**
|
|||
* Creates data to represent the entry file. |
|||
* |
|||
* @param error A pointer to a variable that will contain the error if any. |
|||
* @return The new data: nil for new entries. |
|||
*/ |
|||
- (nullable NSData*)newDataWithError:(NSError**)error; |
|||
|
|||
/**
|
|||
* Creates data to represent the entry file. |
|||
* |
|||
* @param password The password to be used for decryption. |
|||
* @param error A pointer to a variable that will contain the error if any. |
|||
* @return The new data: nil for new entries. |
|||
*/ |
|||
- (nullable NSData*)newDataWithPassword:(nullable NSString*)password error:(NSError**)error; |
|||
|
|||
/**
|
|||
* Creates a data provider to represent the entry file. |
|||
* |
|||
* @param error A pointer to a variable that will contain the error if any. |
|||
* @return The new data provider: nil for new entries. |
|||
*/ |
|||
- (nullable CGDataProviderRef)newDataProviderWithError:(NSError**)error CF_RETURNS_RETAINED; |
|||
|
|||
/**
|
|||
* Creates a data provider to represent the entry file. |
|||
* |
|||
* @param password The password to be used for decryption. |
|||
* @param error A pointer to a variable that will contain the error if any. |
|||
* @return The new data provider: nil for new entries. |
|||
*/ |
|||
- (nullable CGDataProviderRef)newDataProviderWithPassword:(nullable NSString*)password error:(NSError**)error CF_RETURNS_RETAINED; |
|||
|
|||
- (id<ZZArchiveEntryWriter>)newWriterCanSkipLocalFile:(BOOL)canSkipLocalFile; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,79 @@ |
|||
//
|
|||
// ZZConstants.h
|
|||
// ZipZap
|
|||
//
|
|||
// Created by Daniel Cohen Gindi on 29/12/13.
|
|||
// Copyright (c) 2013, Pixelglow Software. All rights reserved.
|
|||
//
|
|||
|
|||
//
|
|||
// Redistribution and use in source and binary forms, with or without modification,
|
|||
// are permitted provided that the following conditions are met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright notice,
|
|||
// this list of conditions and the following disclaimer.
|
|||
//
|
|||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|||
// this list of conditions and the following disclaimer in the documentation
|
|||
// and/or other materials provided with the distribution.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|||
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|||
// THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
typedef NS_ENUM(NSInteger, ZZEncryptionMode) |
|||
{ |
|||
/**
|
|||
* No encryption. |
|||
*/ |
|||
ZZEncryptionModeNone, |
|||
|
|||
/**
|
|||
* Standard PKZIP encryption. |
|||
*/ |
|||
ZZEncryptionModeStandard, |
|||
|
|||
/**
|
|||
* Strong PKZIP encryption. Currently not supported. |
|||
*/ |
|||
ZZEncryptionModeStrong, |
|||
|
|||
/**
|
|||
* WinZip encryption using AES. |
|||
*/ |
|||
ZZEncryptionModeWinZipAES |
|||
}; |
|||
|
|||
typedef NS_ENUM(uint8_t, ZZAESEncryptionStrength) |
|||
{ |
|||
/**
|
|||
* Use 128-bit AES for encryption. |
|||
*/ |
|||
ZZAESEncryptionStrength128 = 0x01, |
|||
|
|||
/**
|
|||
* Use 192-bit AES for encryption. |
|||
*/ |
|||
ZZAESEncryptionStrength192 = 0x02, |
|||
|
|||
/**
|
|||
* Use 256-bit AES for encryption. |
|||
*/ |
|||
ZZAESEncryptionStrength256 = 0x03 |
|||
}; |
|||
|
|||
/**
|
|||
* An NSNumber object that determines whether to create the archive file if it is missing. Creation occurs during -[ZZArchive updateEntries:error:]. Default is @NO. |
|||
*/ |
|||
extern NSString* const ZZOpenOptionsCreateIfMissingKey; |
|||
@ -0,0 +1,136 @@ |
|||
//
|
|||
// ZZError.h
|
|||
// ZipZap
|
|||
//
|
|||
// Created by Glen Low on 25/01/13.
|
|||
// Copyright (c) 2013, Pixelglow Software. All rights reserved.
|
|||
//
|
|||
|
|||
//
|
|||
// Redistribution and use in source and binary forms, with or without modification,
|
|||
// are permitted provided that the following conditions are met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright notice,
|
|||
// this list of conditions and the following disclaimer.
|
|||
//
|
|||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|||
// this list of conditions and the following disclaimer in the documentation
|
|||
// and/or other materials provided with the distribution.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|||
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|||
// THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
/**
|
|||
* The domain of ZipZap errors. |
|||
*/ |
|||
extern NSString* const ZZErrorDomain; |
|||
|
|||
/**
|
|||
* The index of the erroneous entry. |
|||
*/ |
|||
extern NSString* const ZZEntryIndexKey; |
|||
|
|||
typedef NS_ENUM(NSInteger, ZZErrorCode) |
|||
{ |
|||
/**
|
|||
* Cannot open an archive for reading. |
|||
*/ |
|||
ZZOpenReadErrorCode, |
|||
|
|||
/**
|
|||
* Cannot read the end of central directory. |
|||
*/ |
|||
ZZEndOfCentralDirectoryReadErrorCode, |
|||
|
|||
/**
|
|||
* Cannot read a central file header. |
|||
*/ |
|||
ZZCentralFileHeaderReadErrorCode, |
|||
|
|||
/**
|
|||
* Cannot read a local file. |
|||
*/ |
|||
ZZLocalFileReadErrorCode, |
|||
|
|||
/**
|
|||
* Cannot open an archive for writing. |
|||
*/ |
|||
ZZOpenWriteErrorCode, |
|||
|
|||
/**
|
|||
* Cannot write a local file. |
|||
*/ |
|||
ZZLocalFileWriteErrorCode, |
|||
|
|||
/**
|
|||
* Cannot write a central file header. |
|||
*/ |
|||
ZZCentralFileHeaderWriteErrorCode, |
|||
|
|||
/**
|
|||
* Cannot write the end of central directory. |
|||
*/ |
|||
ZZEndOfCentralDirectoryWriteErrorCode, |
|||
|
|||
/**
|
|||
* Cannot replace the zip file after writing. |
|||
*/ |
|||
ZZReplaceWriteErrorCode, |
|||
|
|||
/**
|
|||
* The compression used is currently unsupported. |
|||
*/ |
|||
ZZUnsupportedCompressionMethod, |
|||
|
|||
/**
|
|||
* The encryption used is currently unsupported. |
|||
*/ |
|||
ZZUnsupportedEncryptionMethod, |
|||
|
|||
/**
|
|||
* An invalid CRC checksum has been encountered. |
|||
*/ |
|||
ZZInvalidCRChecksum, |
|||
|
|||
/**
|
|||
* The wrong key was passed in. |
|||
*/ |
|||
ZZWrongPassword, |
|||
|
|||
/**
|
|||
* The data, stream or data consumer block failed but did not set the error. |
|||
* This will be set on the underlying error of the local file write. |
|||
*/ |
|||
ZZBlockFailedWithoutError |
|||
}; |
|||
|
|||
static inline BOOL ZZRaiseErrorNo(NSError** error, ZZErrorCode errorCode, NSDictionary* userInfo) |
|||
{ |
|||
if (error) |
|||
*error = [NSError errorWithDomain:ZZErrorDomain |
|||
code:errorCode |
|||
userInfo:userInfo]; |
|||
return NO; |
|||
} |
|||
|
|||
static inline id ZZRaiseErrorNil(NSError** error, ZZErrorCode errorCode, NSDictionary* userInfo) |
|||
{ |
|||
if (error) |
|||
*error = [NSError errorWithDomain:ZZErrorDomain |
|||
code:errorCode |
|||
userInfo:userInfo]; |
|||
return nil; |
|||
} |
|||
|
|||
@ -0,0 +1,45 @@ |
|||
//
|
|||
// ZipZap.h
|
|||
// ZipZap
|
|||
//
|
|||
// Created by Glen Low on 31/10/12.
|
|||
// Copyright (c) 2012, Pixelglow Software. All rights reserved.
|
|||
//
|
|||
|
|||
//
|
|||
// Redistribution and use in source and binary forms, with or without modification,
|
|||
// are permitted provided that the following conditions are met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright notice,
|
|||
// this list of conditions and the following disclaimer.
|
|||
//
|
|||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|||
// this list of conditions and the following disclaimer in the documentation
|
|||
// and/or other materials provided with the distribution.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|||
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|||
// THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
#import "ZZArchive.h" |
|||
#import "ZZArchiveEntry.h" |
|||
#import "ZZConstants.h" |
|||
#import "ZZError.h" |
|||
|
|||
//! Project version number for ZipZap.
|
|||
FOUNDATION_EXPORT double ZipZapVersionNumber; |
|||
|
|||
//! Project version string for ZipZap.
|
|||
FOUNDATION_EXPORT const unsigned char ZipZapVersionString[]; |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
framework module JLDialUnit { |
|||
umbrella header "JLDialUnit.h" |
|||
export * |
|||
|
|||
module * { export * } |
|||
} |
|||
@ -0,0 +1,127 @@ |
|||
//
|
|||
// DialManager.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by 杰理科技 on 2021/7/20.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JLDialUnit/FatfsObject.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
|
|||
|
|||
typedef NS_ENUM(NSInteger, DialOperateType) { |
|||
DialOperateTypeNoSpace = 0, //空间不足
|
|||
DialOperateTypeDoing = 1, //正在操作
|
|||
DialOperateTypeFail = 2, //操作失败
|
|||
DialOperateTypeSuccess = 3, //操作成功
|
|||
DialOperateTypeUnnecessary = 4, //无需重复打开文件系统
|
|||
DialOperateTypeResetFial = 5, //重置文件系统失败
|
|||
DialOperateTypeNormal = 6, //文件系统正常
|
|||
DialOperateTypeCmdFail = 7, //流程命令执行失败
|
|||
}; |
|||
typedef NS_ENUM(NSInteger, DialUpdateResult) { |
|||
DialUpdateResultFinished = 0, //更新资源完成
|
|||
DialUpdateResultNewest = 1, //资源已最新
|
|||
DialUpdateResultInvalid = 2, //资源无效
|
|||
DialUpdateResultEmpty = 3, //资源为空
|
|||
DialUpdateResultReplace = 4, //资源替换
|
|||
DialUpdateResultAdd = 5, //资源新增
|
|||
DialUpdateResultNoSpace = 6, //空间不足
|
|||
DialUpdateResultZipError = 7, //ZIP资源文件错误
|
|||
DialUpdateResultCompareFail = 8, //表盘资源对比失败
|
|||
DialUpdateResultUpdateUfw = 9, //更新固件 ufw
|
|||
}; |
|||
typedef void(^DialOperateBK)(DialOperateType type, float progress); |
|||
typedef void(^DialListBK)(DialOperateType type, NSArray* __nullable array); |
|||
typedef void(^DialUpdateBK)(DialUpdateResult updateResult, |
|||
NSArray* __nullable array, |
|||
NSString * _Nullable filePath, |
|||
NSInteger index ,float progress); |
|||
|
|||
typedef void(^FatfsFreeBlock)(uint32_t freeSize); |
|||
|
|||
/// 表盘管理类
|
|||
@interface DialManager : NSObject |
|||
|
|||
#pragma mark - 连接成功后,必须调用一次! |
|||
+(void)openDialFileSystemWithCmdManager:(JL_ManagerM *)manager withResult:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 重置表盘系统 |
|||
+(void)resetDialFileSystemWithCmdManager:(JL_ManagerM *)manager withResult:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 查询文件 |
|||
/// 查询文件
|
|||
/// @param result 操作回调
|
|||
+(void)listFile:(DialListBK __nullable)result; |
|||
|
|||
#pragma mark - 添加文件 |
|||
/// 添加文件
|
|||
/// @param file 文件名需要加斜杠,类似@“/WACTH1”。
|
|||
/// @param content 文件数据
|
|||
/// @param result 操作回调
|
|||
+(void)addFile:(NSString*)file |
|||
Content:(NSData*)content |
|||
Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 删除文件 |
|||
/// 删除文件(第一种)
|
|||
/// @param file 文件名需要加斜杠,类似@“/WACTH1”。
|
|||
/// @param result 操作回调
|
|||
+(void)deleteFile:(NSString*)file |
|||
Result:(DialOperateBK)result; |
|||
|
|||
/// 删除文件(第二种)
|
|||
/// @param fileModel JLModel_File类型
|
|||
/// @param result 操作回调
|
|||
+(void)deleteDialResourceWithFileModel:(JLModel_File*)fileModel Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 替换文件 |
|||
/// 替换文件
|
|||
/// @param file 文件名需要加斜杠,类似@“/WACTH1”。
|
|||
/// @param content 文件数据
|
|||
/// @param result 操作回调
|
|||
+(void)repaceFile:(NSString*)file |
|||
Content:(NSData*)content |
|||
Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 格式化外部Flash |
|||
/// 格式化外部Flash操作
|
|||
/// @param handle 设备句柄
|
|||
/// @param result 操作回调
|
|||
+(void)formatFlash:(NSString*)handle Result:(DialOperateBK)result; |
|||
|
|||
#pragma mark - 更新设备的表盘资源(异步调用) |
|||
/// 更新设备的表盘资源(异步调用)
|
|||
/// @param path 资源文件
|
|||
/// @param array 表盘列表(当前)
|
|||
/// @param result 更新结果
|
|||
+(void)updateResourcePath:(NSString*)path |
|||
List:(NSArray*)array |
|||
Result:(DialUpdateBK)result; |
|||
|
|||
/// 获取 fatfs 系统的剩余空间(仅仅fatfs 系统可用)
|
|||
/// 需要异步执行
|
|||
+(uint32_t)getFatfsFree; |
|||
|
|||
/// 获取 fatfs 系统的剩余空间(仅仅fatfs 系统可用)
|
|||
/// @param block 回调空间
|
|||
+(void)getFatfsFree:(FatfsFreeBlock) block; |
|||
|
|||
/// 获取某文件的文件大小
|
|||
/// @param fileName 文件名
|
|||
+(uint32_t)getSizeOfFileName:(NSString*)fileName; |
|||
|
|||
|
|||
/// 记录文件大小(私有接口)
|
|||
/// @param size 文件大小
|
|||
/// @param fileName 文件名
|
|||
+(void)setFileSize:(uint32_t)size FileName:(NSString*)fileName; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,92 @@ |
|||
//
|
|||
// FatfsObject.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by 杰理科技 on 2021/7/20.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
|
|||
|
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
@interface FatfsObject : NSObject |
|||
|
|||
#pragma mark ---> FATFS API |
|||
/// 输入命令中心类,在JL_Entity内。
|
|||
/// @param manager 命令中心类
|
|||
+(void)makeCmdManager:(JL_ManagerM*)manager; |
|||
|
|||
/// 返回 当前 JL_ManagerM
|
|||
+(JL_ManagerM*)outputCmdManager; |
|||
|
|||
/// 设置外挂Flash的大小,FATFS的大小。
|
|||
/// @param flashSize Flash大小
|
|||
/// @param fatsSize FATFS的大小
|
|||
+(BOOL)makeFlashSize:(uint32_t)flashSize |
|||
FatsSize:(uint32_t)fatsSize; |
|||
|
|||
/// 获取Flash上的文件
|
|||
/// @param path 文件名数组,其中"JL",“FONT”不能操作。
|
|||
+(NSArray*)makeListPath:(NSString*)path; |
|||
|
|||
typedef void(^FatfsCreateFile_BK)(float progress); |
|||
/// 新增文件
|
|||
/// @param path “/文件名”
|
|||
/// @param data 文件数据内容
|
|||
/// @param result 进度
|
|||
+(BOOL)makeCreateFile:(NSString*)path |
|||
Content:(NSData* __nullable)data |
|||
Result:(FatfsCreateFile_BK __nullable)result; |
|||
|
|||
typedef void(^FatfsReplaceFile_BK)(float progress); |
|||
/// 替换文件
|
|||
/// @param path “/文件名”
|
|||
/// @param data 文件数据内容
|
|||
+(BOOL)makeReplaceFile:(NSString*)path |
|||
Content:(NSData* __nullable)data |
|||
Result:(FatfsReplaceFile_BK __nullable)result; |
|||
|
|||
/// 删除文件
|
|||
/// @param path “/文件名”
|
|||
+(BOOL)makeRemoveFile:(NSString*)path; |
|||
|
|||
/*---------------------------------------------------------------------------------
|
|||
FatSize -- FAT文件系统认为自己的大小 |
|||
因为小机的FAT项按4K对齐了大小,所以实际上会认为FAT系统占用的空间比FLASH实际大小还要大 |
|||
用 f_getfree 获取的是 FAT文件系统认为自己剩余的空间的簇个数,其中有一部分是在Flash上实际不存在的 |
|||
所以需要减掉这部分 |
|||
计算方式如下: |
|||
FatUsed = FatSize - FreeSize |
|||
FlashRemainSize = FlashSize - FatUsed |
|||
----------------------------------------------------------------------------------*/ |
|||
/// 获取FATFS系统剩余空间,“FreeSize”。
|
|||
+(uint32_t)makeGetFree; |
|||
|
|||
/// 查看watch本间版本
|
|||
/// @param path 文件路径
|
|||
+(NSString*)makeVersionWatch:(NSString*)path; |
|||
|
|||
/// 获取文件前面512个字节
|
|||
/// @param path 文件路径
|
|||
+(NSData *)makeFileHead:(NSString*)path; |
|||
|
|||
/// 读文件
|
|||
/// @param path 文件路径
|
|||
+(NSData*)makeFileContent:(NSString*)path; |
|||
|
|||
/// 解压资源文件
|
|||
/// @param path 文件路径
|
|||
/// @param aimDirection 存放的路径
|
|||
+(NSArray*)unzipFileAtPath:(NSString *)path toDestination:(NSString *)aimDirection; |
|||
|
|||
/// 重置外部flash
|
|||
+(BOOL)makeResetFlash; |
|||
|
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
|
|||
@ -0,0 +1,27 @@ |
|||
//
|
|||
// JLDialSourceModel.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/19.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
|
|||
@interface JLDialSourceModel : JLModel_File |
|||
|
|||
/// 文件大小
|
|||
@property (nonatomic, assign)int size; |
|||
|
|||
/// CRC
|
|||
@property (nonatomic, assign)uint16_t crc; |
|||
|
|||
+(JLDialSourceModel *)createModel:(JLModel_File *)model; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
@ -0,0 +1,30 @@ |
|||
//
|
|||
// JLDialUnit.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2023/2/28.
|
|||
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
//! Project version number for JLDialUnit.
|
|||
FOUNDATION_EXPORT double JLDialUnitVersionNumber; |
|||
|
|||
//! Project version string for JLDialUnit.
|
|||
FOUNDATION_EXPORT const unsigned char JLDialUnitVersionString[]; |
|||
|
|||
// In this header, you should import all the public headers of your framework using statements like #import <JLDialUnit/PublicHeader.h>
|
|||
|
|||
#import <JLDialUnit/DialManager.h> |
|||
#import <JLDialUnit/FatfsObject.h> |
|||
#import <JLDialUnit/ZipZap.h> |
|||
#import <JLDialUnit/ZZArchive.h> |
|||
#import <JLDialUnit/ZZArchiveEntry.h> |
|||
#import <JLDialUnit/ZZConstants.h> |
|||
#import <JLDialUnit/ZZError.h> |
|||
#import <JLDialUnit/JLDialSourceModel.h> |
|||
#import <JLDialUnit/JLDialUnitMgr.h> |
|||
#import <JLDialUnit/JLSourceUpdate.h> |
|||
|
|||
|
|||
@ -0,0 +1,115 @@ |
|||
//
|
|||
// JLDialUnitMgr.h
|
|||
// JLDialUnit
|
|||
//
|
|||
// Created by EzioChan on 2025/3/18.
|
|||
// Copyright © 2025 www.zh-jieli.com. All rights reserved.
|
|||
//
|
|||
|
|||
#import <Foundation/Foundation.h> |
|||
#import <JL_HashPair/JL_HashPair.h> |
|||
#import <JLLogHelper/JLLogHelper.h> |
|||
#import <JL_BLEKit/JL_BLEKit.h> |
|||
|
|||
NS_ASSUME_NONNULL_BEGIN |
|||
@class JLDialSourceModel; |
|||
@interface JLDialUnitMgr : NSObject |
|||
|
|||
/// 设备文件列表
|
|||
@property (nonatomic,strong)NSMutableArray <JLDialSourceModel *> *fileArray; |
|||
|
|||
/// 当前 Flash 操控句柄
|
|||
@property (nonatomic, strong) JLFlashOpMgr *currentFlaghOpMgr; |
|||
|
|||
/// 当前使用的表盘文件
|
|||
@property (nonatomic,strong)JLDialSourceModel *currentFileSource; |
|||
|
|||
/// 当前使用的表盘背景
|
|||
@property (nonatomic,strong)JLDialSourceModel *_Nullable currentBackground; |
|||
|
|||
/// 初始化
|
|||
/// - Parameters:
|
|||
/// - mgr: 蓝牙管理对象
|
|||
/// - completion: 回调
|
|||
-(instancetype)initWithManager:(JL_ManagerM*)mgr completion:(void (^)(NSError * _Nullable))completion; |
|||
|
|||
/// 获取文件列表
|
|||
/// - Parameters:
|
|||
/// - cardType: 设备存储的类型
|
|||
/// - count: 请求的数目
|
|||
/// - completion: 回调
|
|||
/// 返回时,是返回累计数目
|
|||
-(void)getFileList:(JL_CardType)cardType count:(NSInteger)count completion:(void (^)(NSArray <JLDialSourceModel *> * _Nullable,NSError * _Nullable))completion; |
|||
|
|||
/// 清空文件列表
|
|||
/// - Parameter cardType: 设备存储的类型
|
|||
-(void)cleanFileList; |
|||
|
|||
/// 更新文件列表信息
|
|||
/// - Parameters:
|
|||
/// - fileSources: NSArray<JLModel_File *>
|
|||
/// - completion: 回调
|
|||
-(void)updateFileSources:(NSArray<JLModel_File *> *)fileSources completion:(void (^)(NSArray<JLDialSourceModel *> * _Nullable,NSError * _Nullable))completion; |
|||
|
|||
/// 更新文件到设备
|
|||
/// - Parameters:
|
|||
/// - fileHandleType: 设备目标存储句柄
|
|||
/// - fileData: 文件数据
|
|||
/// - filePath: 文件存储路径
|
|||
/// - resultCompletion: 回调
|
|||
/// state: 0:成功 1:传输中 -1:失败
|
|||
/// progress: 传输进度
|
|||
/// error: 错误
|
|||
-(void)updateFileToDevice:(JL_FileHandleType)fileHandleType Data:(NSData *)fileData FilePath:(NSString *)filePath completion:(void (^)(int,double,NSError * _Nullable))resultCompletion; |
|||
|
|||
/// 删除文件
|
|||
/// - Parameters:
|
|||
/// - filePath: 文件路径
|
|||
/// - resultCompletion: 回调
|
|||
-(void)deleteFile:(NSString *)filePath getFileList:(BOOL)isGet Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 删除多个文件
|
|||
/// - Parameters:
|
|||
/// - filePathList: 文件路径
|
|||
/// - resultCompletion: 回调
|
|||
-(void)deleteFiles:(NSArray <NSString*>*) filePathList Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 获取剩余空间
|
|||
/// - Parameter completion: 回调
|
|||
-(void)getRemainingSpace:(void(^)(int freeSize, NSError * _Nullable error))completion; |
|||
|
|||
/// 获取剩余空间 V1
|
|||
/// - Parameter completion: 回调
|
|||
-(void)getFlashRemainingSpace:(void(^)(int freeSize, NSError * _Nullable error))completion; |
|||
|
|||
//MARK: 表盘操作
|
|||
|
|||
/// 获取当前正在使用的表盘
|
|||
/// - Parameter completion: 回调
|
|||
-(void)dialGetCurrent:(void (^)(JLDialSourceModel * _Nullable))completion; |
|||
|
|||
/// 设置当前表盘
|
|||
/// - Parameters:
|
|||
/// - model: 表盘
|
|||
/// - resultCompletion: 回调
|
|||
-(void)dialSetCurrent:(JLDialSourceModel *)model Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 激活自定义表盘背景
|
|||
/// - Parameters:
|
|||
/// - model: 表盘背景对象
|
|||
/// - resultCompletion: 回调
|
|||
-(void)dialActiveCustomBackground:(JLDialSourceModel *)model Completion:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 重置自定义表盘背景
|
|||
/// - Parameter resultCompletion: 回调
|
|||
-(void)dialResetCustomBackground:(void (^)(BOOL state, NSError * _Nullable error))resultCompletion; |
|||
|
|||
/// 获取表盘背景
|
|||
/// - Parameters:
|
|||
/// - path: 路径 诸如“/WATCH”
|
|||
/// - resultCompletion: 回调
|
|||
-(void)dialGetDial:(NSString *)path BackgroundInfo:(void (^)(JLDialSourceModel * _Nullable model, NSError * _Nullable error))resultCompletion; |
|||
|
|||
@end |
|||
|
|||
NS_ASSUME_NONNULL_END |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue