本地文件上传流程
用户从相册或文件选取器选择视频后,App 在本地完成指纹计算与音频提取,再将音频直传对象存储,最后通知 API 创建媒体记录。
流程图
关键步骤
1. 文件指纹
App 使用 computeFileHash 对视频文件计算 SHA-256。相同内容的文件产生相同指纹,触发全局去重。
2. 预签名上传
POST /api/media/upload-url 会:
- 若
fileHash已存在于Media表,返回{ duplicate: true, media },跳过上传 - 否则生成 R2 预签名 PUT URL,对象键格式
audio/{fileHash}.{ext}
3. 本地音频提取
extractAndUploadAudio 调用原生模块 @memshare/expo-media-processor-module:
- 从视频容器中提取音轨(默认 m4a / audio/mp4)
- 通过
expo-file-system直传 R2
音频不经过 API 服务器,降低带宽与延迟。
4. 创建媒体记录
POST /api/media 写入:
sourceType: filesubtitleStatus: pendingsubtitleLanguage: ja(默认)audioS3Key、文件元数据
创建后调用 attachSubtitlesByFileHash:若该指纹已有字幕(其他用户曾上传过),直接将状态置为 success。
5. Worker 转写
若仍为 pending,Worker 领取转写任务。详见 Worker 任务处理。
App 侧本地存储
除云端元数据外,App 还会在设备本地保存视频 URI(video-local-storage),用于离线播放。云端只存音频与字幕,视频本体保留在用户设备。
若本地文件丢失,App 提供重新关联(relink)流程。
失败场景
| 场景 | 表现 |
|---|---|
| 上传 R2 失败 | App 提示错误,不创建媒体 |
| 指纹重复 | 直接加入库,可能已有字幕 |
| Worker 转写失败 | subtitleStatus=failed,subtitleError 可在播放器查看 |