All files / utils videoThumbnail.ts

100% Statements 17/17
100% Branches 4/4
100% Functions 3/3
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58                        7x       7x 7x   1x     7x 1x 1x     6x       4x   2x 2x                   3x   3x   4x 4x 3x         3x    
/**
 * 视频缩略图生成工具
 *
 * 使用 expo-video-thumbnails 生成视频第一帧作为预览
 */
 
/**
 * 生成视频缩略图
 * @param videoUri 视频 URI
 * @returns 缩略图 URI 或 null
 */
export async function generateVideoThumbnail(videoUri: string): Promise<string | null> {
  try {
    // 动态导入 expo-video-thumbnails,如果未安装则返回 null
    // Use require instead of import() for better testability with Jest
    let VideoThumbnails;
    try {
      VideoThumbnails = require('expo-video-thumbnails');
    } catch (e) {
      VideoThumbnails = null;
    }
 
    if (!VideoThumbnails) {
      console.warn('expo-video-thumbnails 未安装,无法生成缩略图');
      return null;
    }
 
    const { uri } = await VideoThumbnails.getThumbnailAsync(videoUri, {
      time: 0, // 获取第一帧
      quality: 0.7,
    });
    return uri;
  } catch (error) {
    console.error('生成视频缩略图失败:', error);
    return null;
  }
}
 
/**
 * 批量生成视频缩略图
 * @param videoUris 视频 URI 数组
 * @returns 缩略图 URI 映射表
 */
export async function generateVideoThumbnails(videoUris: string[]): Promise<Map<string, string>> {
  const thumbnailMap = new Map<string, string>();
 
  await Promise.allSettled(
    videoUris.map(async (uri) => {
      const thumbnail = await generateVideoThumbnail(uri);
      if (thumbnail) {
        thumbnailMap.set(uri, thumbnail);
      }
    })
  );
 
  return thumbnailMap;
}