/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import nativeexport from 'libnativeexport.so';
import { fileIo } from '@kit.CoreFileKit';
import Logger from './Logger';
import { PROGRESS_COMPLETE } from '../constants/CommonConstants';
const TAG = '[NativeExportUtil]';
export interface NativeWatermarkParam {
path: string;
relX: number;
relY: number;
relSize: number;
}
export class NativeExportUtil {
static async exportVideo(
inputPath: string,
outputPath: string,
watermarks: NativeWatermarkParam[],
rotation: number,
onProgress: (percent: number) => void,
onCoverReady: (width: number, height: number) => void
): Promise<number> {
let inputFile: fileIo.File | undefined;
let outputFile: fileIo.File | undefined;
try {
inputFile = fileIo.openSync(inputPath, fileIo.OpenMode.READ_ONLY);
outputFile = fileIo.openSync(outputPath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
fileIo.truncateSync(outputFile.fd);
const stat = fileIo.statSync(inputPath);
// [Start native_wm_params]
const wmParams: nativeexport.WatermarkParam[] = [];
for (let i = 0; i < watermarks.length; i++) {
wmParams.push({
path: watermarks[i].path,
relX: watermarks[i].relX,
relY: watermarks[i].relY,
relSize: watermarks[i].relSize,
});
}
// [End native_wm_params]
// [Start native_export_promise]
return new Promise<number>((resolve) => {
nativeexport.startExport(
inputFile?.fd ?? -1,
0,
stat.size,
outputFile?.fd ?? -1,
wmParams,
rotation,
(percent: number) => {
onProgress(percent);
},
(result: number) => {
if (inputFile) {
try {
fileIo.closeSync(inputFile.fd);
} catch (error) {
Logger.error(TAG, `inputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
}
}
if (outputFile) {
try {
fileIo.closeSync(outputFile.fd);
} catch (error) {
Logger.error(TAG, `outputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
}
}
onProgress(PROGRESS_COMPLETE);
onCoverReady(0, 0);
resolve(result);
}
);
});
// [End native_export_promise]
} catch (e) {
Logger.error(TAG, `exportVideo failed: ${e.code}, ${e.message}`);
if (inputFile) {
try {
fileIo.closeSync(inputFile.fd);
} catch (error) {
Logger.error(TAG, `inputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
}
}
if (outputFile) {
try {
fileIo.closeSync(outputFile.fd);
} catch (error) {
Logger.error(TAG, `outputFile closeSync err, err.code is ${error.code}, message is ${error.message}`);
}
}
return -1;
}
}
// [Start native_cancel]
static cancelExport(): void {
nativeexport.cancelExport();
}
// [End native_cancel]
}