更新记录
1.0.0(2025-10-16)
- 首发版本
平台兼容性
uni-app(4.71)
Vue2 | Vue2插件版本 | Vue3 | Vue2插件版本 | Chrome | Safari | app-vue | app-nvue | Android | iOS | iOS插件版本 | 鸿蒙 |
---|---|---|---|---|---|---|---|---|---|---|---|
√ | 1.0.0 | √ | 1.0.0 | - | - | - | - | - | 16 | 1.0.0 | - |
微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 快应用-华为 | 快应用-联盟 |
---|---|---|---|---|---|---|---|---|---|---|
- | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.71)
Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
---|---|---|---|---|---|
- | - | - | - | - | - |
UTS环境兼容性
uni-app | uni-app x |
---|---|
√ | √ |
sn-parse-livephoto
插件简介
sn-parse-livephoto
是一个用于将视频转换为 iOS Live Photo 格式的 UTS 插件。该插件支持从视频文件或相册中选择的视频创建 Live Photo,并自动保存到系统相册中。
注意:本插件仅支持 iOS 平台
功能特性
- 🎥 从相册选择视频并转换为 Live Photo
- 📁 从本地视频文件创建 Live Photo
- ⏰ 支持自定义封面时间点
- ✂️ 支持视频片段裁剪
- 📱 自动保存到系统相册
- 🔧 基于 UTS 开发,性能优异
安装配置
1. 插件安装
在项目中引入插件:
import { pick2Livephoto, parseLivephoto } from '@/uni_modules/sn-parse-livephoto'
2. 权限配置
在 manifest.json
中添加相册权限:
{
"ios": {
"privacyDescription": {
"NSPhotoLibraryUsageDescription": "需要访问相册以选择视频并创建 Live Photo",
"NSPhotoLibraryAddUsageDescription": "需要访问相册以保存 Live Photo"
}
}
}
API 接口
pick2Livephoto
从相册选择视频并转换为 Live Photo。
参数:
interface SnParsePickerLivephotoParams {
coverTime?: number; // 可选,封面时间点(秒),默认为视频中间位置
videoRange?: number[]; // 可选,视频片段范围 [开始时间, 结束时间](秒)
}
回调参数:
interface SnParseLivephotoResult {
code: number; // 0: 成功, -1: 失败
data: UTSJSONObject; // 结果数据
}
使用示例:
import { pick2Livephoto } from '@/uni_modules/sn-parse-livephoto'
// 选择视频并创建 Live Photo
pick2Livephoto({
coverTime: 2.0, // 封面时间设为2秒
videoRange: [1.0, 5.0] // 只使用1-5秒的视频片段
}, (result) => {
if (result.code === 0) {
console.log('Live Photo 创建成功')
uni.showToast({
icon: 'success',
title: 'Live Photo 创建成功'
})
} else {
console.error('创建失败:', result.data.errMsg)
uni.showToast({
icon: 'error',
title: result.data.errMsg || '创建失败'
})
}
})
parseLivephoto
从本地视频文件创建 Live Photo。
参数:
interface SnParseLivephotoParams {
video: string; // 必需,视频文件路径
coverTime?: number; // 可选,封面时间点(秒)
videoRange?: number[]; // 可选,视频片段范围 [开始时间, 结束时间](秒)
}
回调参数:
interface SnParseLivephotoResult {
code: number; // 0: 成功, -1: 失败
data: UTSJSONObject; // 结果数据
}
使用示例:
import { parseLivephoto } from '@/uni_modules/sn-parse-livephoto'
// 从本地视频文件创建 Live Photo
const videoPath = plus.io.convertLocalFileSystemURL('/static/test.mov')
parseLivephoto({
video: videoPath,
coverTime: 1.5, // 封面时间设为1.5秒
videoRange: [0.5, 3.0] // 只使用0.5-3秒的视频片段
}, (result) => {
if (result.code === 0) {
console.log('Live Photo 创建成功')
uni.showToast({
icon: 'success',
title: 'Live Photo 创建成功'
})
} else {
console.error('创建失败:', result.data.errMsg)
uni.showToast({
icon: 'error',
title: result.data.errMsg || '创建失败'
})
}
})
完整使用示例
<template>
<view class="container">
<view class="section">
<text class="title">Live Photo 创建工具</text>
<button type="primary" @click="pickVideoFromAlbum" class="btn">
从相册选择视频
</button>
<button type="default" @click="createFromLocalVideo" class="btn">
从本地视频创建
</button>
<view class="settings" v-if="showSettings">
<text class="label">封面时间点(秒):</text>
<input v-model="coverTime" type="number" placeholder="例如:2.0" />
<text class="label">视频片段范围:</text>
<view class="range-input">
<input v-model="videoStart" type="number" placeholder="开始时间" />
<text>-</text>
<input v-model="videoEnd" type="number" placeholder="结束时间" />
</view>
</view>
<button type="default" @click="toggleSettings" class="btn-small">
{{ showSettings ? '隐藏' : '显示' }}高级设置
</button>
</view>
</view>
</template>
<script>
import { pick2Livephoto, parseLivephoto } from '@/uni_modules/sn-parse-livephoto'
export default {
data() {
return {
showSettings: false,
coverTime: 2.0,
videoStart: 1.0,
videoEnd: 5.0
}
},
methods: {
// 从相册选择视频
pickVideoFromAlbum() {
const params = {
coverTime: parseFloat(this.coverTime) || undefined
}
// 如果设置了视频范围
if (this.videoStart && this.videoEnd) {
params.videoRange = [
parseFloat(this.videoStart),
parseFloat(this.videoEnd)
]
}
pick2Livephoto(params, (result) => {
this.handleResult(result)
})
},
// 从本地视频创建
createFromLocalVideo() {
// 选择本地视频文件
uni.chooseMedia({
count: 1,
mediaType: ['video'],
sourceType: ['album'],
success: (res) => {
const videoPath = plus.io.convertLocalFileSystemURL(res.tempFiles[0].tempFilePath)
const params = {
video: videoPath,
coverTime: parseFloat(this.coverTime) || undefined
}
// 如果设置了视频范围
if (this.videoStart && this.videoEnd) {
params.videoRange = [
parseFloat(this.videoStart),
parseFloat(this.videoEnd)
]
}
parseLivephoto(params, (result) => {
this.handleResult(result)
})
},
fail: (err) => {
console.error('选择视频失败:', err)
uni.showToast({
icon: 'error',
title: '选择视频失败'
})
}
})
},
// 处理结果
handleResult(result) {
if (result.code === 0) {
uni.showToast({
icon: 'success',
title: 'Live Photo 创建成功'
})
console.log('创建成功:', result.data.message)
} else {
uni.showToast({
icon: 'error',
title: result.data.errMsg || '创建失败'
})
console.error('创建失败:', result.data.errMsg)
}
},
// 切换设置显示
toggleSettings() {
this.showSettings = !this.showSettings
}
}
}
</script>
<style>
.container {
padding: 20px;
}
.section {
margin-bottom: 30px;
}
.title {
font-size: 18px;
font-weight: bold;
margin-bottom: 20px;
display: block;
}
.btn {
width: 100%;
margin-bottom: 10px;
}
.btn-small {
width: 100%;
font-size: 14px;
}
.settings {
margin: 20px 0;
padding: 15px;
background: #f5f5f5;
border-radius: 8px;
}
.label {
display: block;
margin: 10px 0 5px 0;
font-size: 14px;
color: #666;
}
input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 10px;
}
.range-input {
display: flex;
align-items: center;
gap: 10px;
}
.range-input input {
flex: 1;
margin-bottom: 0;
}
</style>
注意事项
平台限制
- 仅支持 iOS 平台,Android 平台不支持
- 需要 iOS 12.0 及以上版本
- 需要支持 Live Photo 的设备
权限要求
- 需要相册访问权限(NSPhotoLibraryUsageDescription)
- 需要相册写入权限(NSPhotoLibraryAddUsageDescription)
- 首次使用时会自动请求权限
文件要求
- 支持的视频格式:MP4、MOV、M4V 等
- 视频时长建议在 1-15 秒之间
- 视频文件大小建议不超过 100MB
性能建议
- 视频片段长度建议控制在 5 秒以内
- 避免同时处理多个视频文件
- 大文件处理时建议显示加载提示
错误处理
- 请务必处理回调中的错误情况
- 常见错误包括权限拒绝、文件不存在、格式不支持等
- 建议在用户操作前检查权限状态
错误码说明
code: 0
- 操作成功code: -1
- 操作失败
常见错误信息:
- "复制视频失败" - 文件复制过程中出错
- "修复错误" - 视频文件处理失败
- "用户取消选择" - 用户在相册选择界面取消了操作
- "无法获取视频资源" - 选择的不是有效的视频文件
- "视频文件不存在" - 传入的文件路径对应的文件不存在
- "创建 Live Photo 失败" - 无法将视频转换为 Live Photo