模板版本:v0.4.0

react-native-compressor

本项目基于 react-native-compressor 开发。

三方库名称 三方库版本 发布信息 支持RN版本 Autolink 编译API版本 社区基线版本 npm地址
@react-native-ohos/react-native-compressor ~ 1.16.1 Gitcode Releases 0.72.* / 0.77.* API12+ 1.16.0 Npm Address

简介

React Native Compressor 是一个功能强大的媒体压缩库,类似于 WhatsApp 的压缩方式,支持自动/手动压缩、后台上传和文件下载。

下载安装

进入到工程目录并输入以下命令:

npm

npm install @react-native-ohos/react-native-compressor

yarn

yarn add @react-native-ohos/react-native-compressor
是否支持autolink RN框架版本
~ 1.16.1 No 0.72
~ 1.16.1 No 0.77

使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md

如您使用的版本支持Autolink,并且工程已接入Autolink,可跳过ManualLink配置。

ManualLink: 此步骤为手动配置原生依赖项的指导

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony

1. Overrides RN SDK

为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。

关于该字段的作用请阅读官方说明

{
  "overrides": {
    "@rnoh/react-native-openharmony": "^0.72.38" // ohpm 在线版本
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
  }
}

2. 引入原生端代码

目前有两种方法:

  • 通过 har 包引入;
  • 直接链接源码。

方法一:通过 har 包引入(推荐)

har 包位于三方库安装路径的 `harmony` 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
    "@react-native-ohos/react-native-compressor": "file:../../node_modules/@react-native-ohos/react-native-compressor/harmony/compressor.har"
  }

点击右上角的 sync 按钮

或者在命令行终端执行:

cd entry
ohpm install

方法二:直接链接源码

如需使用直接链接源码,请参考[直接链接源码说明](./link-source-code.md)

3. 配置 CMakeLists 和引入 CompressorPackage

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-compressor/harmony/compressor/src/main/cpp" ./compressor)
# RNOH_END: manual_package_linking_1

file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_compressor)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "SamplePackage.h"
+ #include "CompressorPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
      std::make_shared<SamplePackage>(ctx),
+     std::make_shared<CompressorPackage>(ctx)
    };
}

4. 在 ArkTs 侧引入 CompressorPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

  ...
+ import { CompressorPackage } from '@react-native-ohos/react-native-compressor/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
+    new CompressorPackage(ctx)
  ];
}

运行

点击右上角的 sync 按钮

或者在命令行终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

本文档内容基于以下版本验证通过:

RNOH: 0.72.90; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112; RNOH: 0.77.18; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;

权限要求

  • 如果使用网络文件压缩或上传/下载功能,应用需要申请网络权限

    entry/src/main/module.json5中添加

requestPermissions: [
  {
    "name": "ohos.permission.INTERNET",
  },
],

使用示例

下面的代码展示了这个库的基本使用场景:

使用时 import 的库名不变。

import React, { useState } from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
  Alert,
  ScrollView,
  ActivityIndicator,
  TextInput
} from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import {
  Video,
  Audio,
  Image,
  backgroundUpload,
  download,
  clearCache,
  getFileSize,
  UploadType,
  UploaderHttpMethod,
} from 'react-native-compressor';

const CompressorPage = () => {
  const [loading, setLoading] = useState(false);
  const [filePath, setFilePath] = useState('');
  const [uploadUrl, setUploadUrl] = useState('');
  const [downloadUrl, setDownloadUrl] = useState('');

  const pickFile = async () => {
    try {
      const result = await DocumentPicker.pick({
        type: [DocumentPicker.types.allFiles],
      });
      setFilePath(result[0].uri);
      Alert.alert('成功', `已选择文件: ${result[0].name}`);
    } catch (error) {
      if (DocumentPicker.isCancel(error)) {
        Alert.alert('错误', '用户取消选择');
      } else {
        Alert.alert('错误', '选择文件失败');
      }
    }
  };

  const showResult = (message: string) => {
    Alert.alert('结果', message);
  };

  const showError = (error: any) => {
    Alert.alert('错误', error?.message || '操作失败');
  };

  const compressImage = async () => {
    if (!filePath) {
      Alert.alert('提示', '请先选择文件');
      return;
    }
    setLoading(true);
    try {
      const result = await Image.compress(filePath);
      showResult(`压缩后的图片路径: ${result}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  const compressVideo = async () => {
    if (!filePath) {
      Alert.alert('提示', '请先选择文件');
      return;
    }
    setLoading(true);
    try {
      const result = await Video.compress(filePath);
      showResult(`压缩后的视频路径: ${result}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  const compressAudio = async () => {
    if (!filePath) {
      Alert.alert('提示', '请先选择文件');
      return;
    }
    setLoading(true);
    try {
      const result = await Audio.compress(filePath);
      showResult(`压缩后的音频路径: ${result}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  const getFileInfo = async () => {
    if (!filePath) {
      Alert.alert('提示', '请先选择文件');
      return;
    }
    setLoading(true);
    try {
      const size = await getFileSize(filePath);
      showResult(`文件大小: ${size}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  const clearCacheDir = async () => {
    setLoading(true);
    try {
      const result = await clearCache();
      showResult(`清除缓存结果: ${result}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  const uploadFile = async () => {
    if (!filePath || !uploadUrl) {
      Alert.alert('提示', '请先选择文件并输入上传URL');
      return;
    }
    setLoading(true);
    try {
      const uploadId = await backgroundUpload(
        uploadUrl,
        filePath,
        {
          httpMethod: UploaderHttpMethod.POST,
          headers: {
            'Authorization': 'Bearer token',
          },
          uploadType: UploadType.MULTIPART,
        }
      );
      showResult(`上传ID: ${uploadId}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  const downloadFile = async () => {
    if (!downloadUrl) {
      Alert.alert('提示', '请输入下载URL');
      return;
    }
    setLoading(true);
    try {
      const result = await download(downloadUrl);
      showResult(`下载结果: ${result}`);
    } catch (error) {
      showError(error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <ScrollView style={styles.container}>
      <Text style={styles.title}>React Native Compressor</Text>

      {loading && (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color="#007AFF" />
          <Text style={styles.loadingText}>处理中...</Text>
        </View>
      )}

      <View style={styles.section}>
        <Text style={styles.label}>选择文件</Text>
        <TouchableOpacity style={styles.button} onPress={pickFile}>
          <Text style={styles.buttonText}>选择文件</Text>
        </TouchableOpacity>
        {filePath ? (
          <View style={styles.pathContainer}>
            <Text style={styles.pathLabel}>文件路径:</Text>
            <Text style={styles.pathText} numberOfLines={2}>
              {filePath}
            </Text>
          </View>
        ) : null}
      </View>

      <View style={styles.section}>
        <Text style={styles.label}>压缩功能</Text>
        <TouchableOpacity style={styles.button} onPress={compressImage}>
          <Text style={styles.buttonText}>压缩图片</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.button} onPress={compressVideo}>
          <Text style={styles.buttonText}>压缩视频</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.button} onPress={compressAudio}>
          <Text style={styles.buttonText}>压缩音频</Text>
        </TouchableOpacity>
      </View>

      <View style={styles.section}>
        <Text style={styles.label}>文件操作</Text>
        <TouchableOpacity style={styles.button} onPress={getFileInfo}>
          <Text style={styles.buttonText}>获取文件大小</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.button} onPress={clearCacheDir}>
          <Text style={styles.buttonText}>清除缓存</Text>
        </TouchableOpacity>
      </View>

      <View style={styles.section}>
        <Text style={styles.label}>上传下载</Text>
        <TextInput
          style={styles.input}
          placeholder="输入上传URL"
          value={uploadUrl}
          onChangeText={setUploadUrl}
        />
        <TouchableOpacity style={styles.button} onPress={uploadFile}>
          <Text style={styles.buttonText}>上传文件</Text>
        </TouchableOpacity>
        <TextInput
          style={styles.input}
          placeholder="输入下载URL"
          value={downloadUrl}
          onChangeText={setDownloadUrl}
        />
        <TouchableOpacity style={styles.button} onPress={downloadFile}>
          <Text style={styles.buttonText}>下载文件</Text>
        </TouchableOpacity>
      </View>
    </ScrollView>

  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#F5F5F5',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 20,
    color: '#333',
  },
  loadingContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 10,
    backgroundColor: '#E3F2FD',
    borderRadius: 8,
    marginBottom: 20,
  },
  loadingText: {
    marginLeft: 10,
    color: '#007AFF',
  },
  section: {
    backgroundColor: '#FFFFFF',
    padding: 15,
    borderRadius: 8,
    marginBottom: 15,
  },
  label: {
    fontSize: 16,
    fontWeight: 'bold',
    marginBottom: 10,
    color: '#333',
  },
  button: {
    backgroundColor: '#007AFF',
    padding: 12,
    borderRadius: 8,
    alignItems: 'center',
    marginBottom: 10,
  },
  buttonText: {
    color: '#FFFFFF',
    fontSize: 14,
    fontWeight: '600',
  },
  pathContainer: {
    backgroundColor: '#F9F9F9',
    padding: 10,
    borderRadius: 8,
    marginTop: 10,
  },
  pathLabel: {
    fontSize: 12,
    color: '#666',
    marginBottom: 5,
  },
  pathText: {
    fontSize: 12,
    color: '#333',
  },
});

export default CompressorPage;

使用说明

视频压缩

import React from "react";
import { View, Button, Text } from "react-native";
import { Video } from "@react-native-ohos/react-native-compressor";

const VideoCompressorExample = () => {
  const [compressedPath, setCompressedPath] = React.useState("");

  const compressVideo = async () => {
    try {
      const result = await Video.compress(
        "file://path/to/video.mp4",
        {
          compressionMethod: "auto",
          maxSize: 640,
          minimumFileSizeForCompress: 10,
        },
        (progress) => {
          console.log("Compression progress:", progress);
        }
      );
      setCompressedPath(result);
    } catch (error) {
      console.error("Compression failed:", error);
    }
  };

  return (
    <View style={{ padding: 20 }}>
      <Button title="Compress Video" onPress={compressVideo} />
      {compressedPath && <Text>Compressed: {compressedPath}</Text>}
    </View>
  );
};

export default VideoCompressorExample;

音频压缩

import { Audio } from "@react-native-ohos/react-native-compressor";

const compressAudio = async () => {
  try {
    const result = await Audio.compress(
      "file://path/to/audio.mp3",
      {
        quality: "medium",
        bitrate: 128000,
        samplerate: 44100,
        channels: 2
      }
    );
    console.log("Compressed audio:", result);
  } catch (error) {
    console.error("Compression failed:", error);
  }
};

图片压缩

import { Image } from "@react-native-ohos/react-native-compressor";

const compressImage = async () => {
  try {
    const result = await Image.compress(
      "file://path/to/image.jpg",
      {
        compressionMethod: "auto",
        maxWidth: 1280,
        maxHeight: 1280,
        quality: 0.8,
        output: "jpg"
      }
    );
    console.log("Compressed image:", result);
  } catch (error) {
    console.error("Compression failed:", error);
  }
};

文件上传

import { backgroundUpload, UploadType, UploaderHttpMethod } from "@react-native-ohos/react-native-compressor";

const uploadFile = async () => {
  try {
    const result = await backgroundUpload(
      "https://example.com/upload",
      "file://path/to/file.mp4",
      {
        uploadType: UploadType.MULTIPART,
        httpMethod: UploaderHttpMethod.POST,
        fieldName: "file",
        mimeType: "video/mp4",
        headers: {
          "Authorization": "Bearer token"
        }
      },
      (written, total) => {
        console.log(`Upload progress: ${written}/${total}`);
      }
    );
    console.log("Upload result:", result);
  } catch (error) {
    console.error("Upload failed:", error);
  }
};

文件下载

import { download } from "@react-native-ohos/react-native-compressor";

const downloadFile = async () => {
  try {
    const result = await download(
      "https://example.com/file.mp4",
      (progress) => {
        console.log("Download progress:", progress);
      }
    );
    console.log("Downloaded file:", result);
  } catch (error) {
    console.error("Download failed:", error);
  }
};

创建视频缩略图

import { createVideoThumbnail } from "@react-native-ohos/react-native-compressor";

const createThumbnail = async () => {
  try {
    const thumbnail = await createVideoThumbnail(
      "file://path/to/video.mp4",
      {
        headers: {
          "Authorization": "Bearer token"
        }
      }
    );
    console.log("Thumbnail:", thumbnail);
    // { path, size, mime, width, height }
  } catch (error) {
    console.error("Failed to create thumbnail:", error);
  }
};

获取媒体元数据

import { getVideoMetaData, getImageMetaData } from "@react-native-ohos/react-native-compressor";

const getVideoInfo = async () => {
  try {
    const info = await getVideoMetaData("file://path/to/video.mp4");
    console.log("Video metadata:", info);
    // { extension, size, duration, width, height }
  } catch (error) {
    console.error("Failed to get video metadata:", error);
  }
};

const getImageInfo = async () => {
  try {
    const info = await getImageMetaData("file://path/to/image.jpg");
    console.log("Image metadata:", info);
    // { ImageWidth, ImageHeight, Orientation, size, extension, exif }
  } catch (error) {
    console.error("Failed to get image metadata:", error);
  }
};

清理缓存

import { clearCache } from "@react-native-ohos/react-native-compressor";

const cleanCache = async () => {
  try {
    const result = await clearCache();
    console.log("Cache cleared:", result);
  } catch (error) {
    console.error("Failed to clear cache:", error);
  }
};

接口说明

"Platform"列表示该属性在原三方库上支持的平台。

"HarmonyOS Support"列为 yes 表示 HarmonyOS平台支持 该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

Image

名称 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
compress value:string,
options?: CompressorOptions
Promise<string> No Android/IOS Yes 压缩图片文件

CompressorOptions

属性 类型 必填 平台 HarmonyOS平台支持 描述
compressionMethod 'auto' | 'manual' No Android/IOS Yes 压缩模式
maxWidth number No Android/IOS Yes 最大宽度
maxHeight number No Android/IOS Yes 最大高度
quality number No Android/IOS Yes 压缩质量 (0-1)
input 'base64' | 'uri' No Android/IOS Yes 输入类型
output 'jpg' | 'png' No Android/IOS Yes 输出格式
disablePngTransparency boolean No Android/IOS Yes 设置成true时,它会将PNG图像的透明背景转白色背景,从而可以使用质量压缩参数,默认情况为false,PNG图像保持透明背景,质量参数被忽略
returnableOutputType 'uri' | 'base64' No Android/IOS Yes 返回类型
progressDivider number No Android/IOS Yes 进度回调间隔
downloadProgress (progress: number) => void No Android/IOS Yes 下载进度回调

Video

名称 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
compress fileUrl:string,
options?: videoCompresssionType,
onProgress?: (progress: number) => void
Promise<string> No Android/IOS Yes 压缩图片文件
cancelCompression cancellationId: string void No Android/IOS Yes 取消视频压缩
activateBackgroundTask onExpired?: (data: any) => void Promise<any> No Android/IOS Yes 激活后台任务
deactivateBackgroundTask \ Promise<any> No Android/IOS Yes 停用后台任务

videoCompresssionType

属性 类型 必填 平台 HarmonyOS平台支持 描述
bitrate number No Android/IOS Yes 比特率
maxSize number No Android/IOS Yes 最大尺寸
compressionMethod 'auto' | 'manual' No Android/IOS Yes 压缩模式
minimumFileSizeForCompress number No Android/IOS Yes 最小压缩阈值
getCancellationId (id: string) => void No Android/IOS Yes 获取取消ID回调
downloadProgress (progress: number) => void No Android/IOS Yes 下载进度回调
progressDivider number No Android/IOS Yes 进度回调间隔

Audio

名称 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
compress url:string,
options?: audioCompresssionType
Promise<string> No Android/IOS Yes 压缩音频文件

audioCompresssionType

属性 类型 必填 平台 HarmonyOS平台支持 描述
bitrate number No Android/IOS Yes 比特率 (64000-320000)
quality 'low' | 'medium' | 'high' No Android/IOS Yes 质量级别
samplerate number No Android/IOS Yes 采样率 (44100-192000)
channels number No Android/IOS Yes 声道数 (1或2)

工具函数接口

名称 参数类型 返回值 必填 平台 HarmonyOS平台支持 描述
backgroundUpload url: string,
fileUrl: string,
options: UploaderOptions, onProgress?: (written: number, total: number) => void,
abortSignal?: AbortSignal
Promise No Android/IOS Yes 后台上传文件
download fileUrl: string,
downloadProgress?: (progress: number) => void,
progressDivider?: number
Promise No Android/IOS Yes 下载文件
cancelUpload uuid?: sting,
shouldCancelAll?: boolean
void No Android/IOS Yes 取消上传任务
createVideoThumbnail fileUrl: string,
options?: {headers?: {[key: sting]: string}}
Promise<{path: string,
size: number,
mime: string,
width: number,
height: number}>
No Android/IOS Yes 创建视频缩略图
getVideoMetaData filePath: string Promise<{extension: string,
size: number,
duration: number,
width: number,
height: number}>
No Android/IOS Yes 获取视频元数据
getImageMetaData filePath: string Promise<{ImageWidth: number,
ImageHeight: number,
Orientation: number,
size: number,
extension: string,
exif: {[key: string]: string}}>
No Android/IOS Yes 获取图片元数据
clearCache cacheDir?: string Promise<string> No Android/IOS Yes 清理缓存
generateFilePath extension: string Promise<\string> No Android/IOS Yes 生成临时文件路径
getFileSize filePath: string Promise<\string> No Android/IOS Yes 获取文件大小
getRealPath path: string,
type: string = 'video' | 'image'(鸿蒙不支持)
Promise<\string> No Android/IOS Yes 获取文件真实路径

UploaderOptions

uploadType为UploadType.BINARY_CONTENT时

属性 类型 必填 平台 HarmonyOS平台支持 描述
uploadType UploadType.BINARY_CONTENT No Android/IOS Yes 上传类型
mimeType string No Android/IOS Yes MIME类型
httpMethod UploaderHttpMethod | HttpMethod No Android/IOS Yes 上传请求类型
getCancellationId (cancellationId: string) => void No Android/IOS Yes 获取取消ID回调
headers Record<string, string> No Android/IOS Yes 自定义HTTP头

uploadType为UploadType.MULTIPART时

属性 类型 必填 平台 HarmonyOS平台支持 描述
uploadType UploadType.MULTIPART Yes Android/IOS Yes 上传类型
fieldName string No Android/IOS Yes 表单字段名
mimeType string No Android/IOS Yes MIME类型
parameters Record<string, string> No Android/IOS Yes 额外表单字段
headers Record<string, string> No Android/IOS Yes 自定义HTTP头
httpMethod UploaderHttpMethod | HttpMethod No Android/IOS Yes 上传请求类型
getCancellationId (cancellationId: string) => void No Android/IOS Yes 获取取消ID回调

HttpMethod = 'POST' | 'PUT' | 'PATCH'

名称 平台 HarmonyOS平台支持 描述
'POST' Android/IOS Yes POST 请求
'PUT' Android/IOS Yes PUT 请求
'PATCH' Android/IOS No PATCH 请求

枚举类型

UploadType

名称 平台 HarmonyOS平台支持 描述
BINARY_CONTENT 0 Android/IOS Yes 二进制内容上传
MULTIPART 1 Android/IOS Yes multipart表单上传

UploaderHttpMethod

名称 平台 HarmonyOS平台支持 描述
POST 'POST' Android/IOS Yes POST 请求
PUT 'PUT' Android/IOS Yes PUT 请求
PATCH 'PATCH' Android/IOS No PATCH 请求

遗留问题

UploaderHttpMethod,HttpMethod的属性PATCH,getRealPath接口的参数type鸿蒙化适配不支持 issue # 2

压缩不支持的媒体文件格式issue # 4

其他

  1. 视频缩率图的尺寸规格最大边为512,另一条边根据视频的原始宽高比进行缩放得到。

  2. 压缩支持的媒体文件格式:
    支持图片格式:JPEG、PNG、GIF、BMP、WebP、HEIC
    支持视频格式:MP4、MKV、3gp(API22+)
    支持音频格式:WAV、MP3、MP4

目录结构

/react-native-compressor  # 项目根目录
├── harmony              # 鸿蒙适配代码
│    └─ compressor.har          # har包
│    └─ compressor                  # 鸿蒙适配核心代码
│          └─ src/main/ets
│              └─ CompressorModule.ts  # 主要功能实现
│              └─ common/type.ts  # 类型定义
│          └─ src/main/cpp  # C++ 原生代码
│              └─ capbilities/  # 音频编解码
│              └─ transcoding/  # 转码功能
├── src            # RN代码
│    └─ index.tsx  # 入口文件
│    └─ Video/  # 视频压缩模块
│    └─ Audio/  # 音频压缩模块
│    └─ Image/  # 图片压缩模块
│    └─ utils/  # 工具函数
│    └─ Spec/  # TypeScript 类型定义
├── README.md           # 英文安装使用方法
├── package.json  # 包配置

贡献代码

使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR

开源协议

本项目基于 MIT License ,请自由地享受和参与开源。