2025-07-17 15:44:34 +08:00

103 lines
3.4 KiB
TypeScript

import * as FileSystem from 'expo-file-system';
import { confirmUpload, getUploadUrl } from './api';
import { ExtendedAsset } from './types';
import { uploadFile } from './uploader';
// 将 HEIC 图片转化
export const convertHeicToJpeg = async (uri: string): Promise<File> => {
try {
console.log('Starting HEIC to JPEG conversion for:', uri);
// 1. 将文件复制到缓存目录
const cacheDir = FileSystem.cacheDirectory;
if (!cacheDir) {
throw new Error('Cache directory not available');
}
// 创建唯一的文件名
const tempUri = `${cacheDir}${Date.now()}.heic`;
// 复制文件到缓存目录
await FileSystem.copyAsync({
from: uri,
to: tempUri
});
// 2. 检查文件是否存在
const fileInfo = await FileSystem.getInfoAsync(tempUri);
if (!fileInfo.exists) {
throw new Error('Temporary file was not created');
}
// 3. 读取文件为 base64
const base64 = await FileSystem.readAsStringAsync(tempUri, {
encoding: FileSystem.EncodingType.Base64,
});
if (!base64) {
throw new Error('Failed to read file as base64');
}
// 5. 创建文件名
const originalName = uri.split('/').pop() || 'converted';
const filename = originalName.replace(/\.(heic|heif)$/i, '.jpg');
console.log('Successfully converted HEIC to JPEG:', filename);
// 清理临时文件
try {
await FileSystem.deleteAsync(tempUri, { idempotent: true });
} catch (cleanupError) {
console.warn('Failed to clean up temporary file:', cleanupError);
}
return new File([blob], filename, { type: 'image/jpeg' });
} catch (error: unknown) {
console.error('Detailed HEIC conversion error:', {
error: error instanceof Error ? {
message: error.message,
name: error.name,
stack: error.stack
} : error,
uri: uri
});
throw new Error(`Failed to convert HEIC image: ${error instanceof Error ? error.message : 'An unknown error occurred'}`);
}
};
// 压缩图片
import { compressImage } from '../image-process/imageCompress';
// 提取视频的首帧进行压缩并上传
export const uploadVideoThumbnail = async (asset: ExtendedAsset) => {
try {
const manipResult = await compressImage(asset.uri);
const response = await fetch(manipResult.uri);
const blob = await response.blob();
const filename = asset.filename ?
`compressed_${asset.filename}` :
`image_${Date.now()}_compressed.jpg`;
const compressedFile = new File([blob], filename, { type: 'image/jpeg' });
const { upload_url, file_id } = await getUploadUrl(compressedFile, {
originalUri: asset.uri,
creationTime: asset.creationTime,
mediaType: 'image',
isCompressed: true
});
await uploadFile(compressedFile, upload_url);
await confirmUpload(file_id);
console.log('视频首帧文件上传成功:', {
fileId: file_id,
filename: compressedFile.name,
type: compressedFile.type
});
return { success: true, file_id };
} catch (error) {
return { success: false, error };
}
};