Skip to content

Commit cf0a2c4

Browse files
authored
Merge pull request #155 from excitedcat/issue/154
docs(openVideoPicker): add openVideoPicker api to readme. close #154
2 parents e1f34c1 + 8c5a5dc commit cf0a2c4

File tree

6 files changed

+132
-25
lines changed

6 files changed

+132
-25
lines changed

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,61 @@ SyanImagePicker.openCamera(options, (err, photos) => {
314314
})
315315
```
316316

317+
### 选择视频
318+
319+
```javascript
320+
SyanImagePicker.openVideoPicker(options, (err, videos) => {
321+
if (err) {
322+
// 取消选择
323+
return;
324+
}
325+
// 选择成功,处理视频
326+
// ...
327+
})
328+
```
329+
330+
options 可选配置:
331+
332+
```
333+
{
334+
MaxSecond: 60,
335+
MinSecond: 0,
336+
recordVideoSecond: 60,
337+
videoCount: 1
338+
}
339+
```
340+
341+
返回结果:
342+
343+
| type | value | iOS | Android |
344+
|---|---|---|---|
345+
| uri | string |||
346+
| fileName | string |||
347+
| size | string |||
348+
| duration | number |||
349+
| width | number |||
350+
| height | number |||
351+
| type | string |||
352+
| mime | string |||
353+
| coverUri | string |||
354+
| favorite | string |||
355+
| mediaType | string |||
356+
357+
Android 返回结果:
358+
359+
```javascript
360+
{
361+
"mime": "video/mp4",
362+
"type": "video",
363+
"height": 1080,
364+
"width": 1920,
365+
"duration": 30.22,
366+
"size": 63876724,
367+
"fileName": "VID_20200409_11492864.mp4",
368+
"uri": "file:///storage/emulated/0/DCIM/Camera/VID_20200409_11492864.mp4"
369+
}
370+
```
371+
317372
### 删除缓存
318373
```javascript
319374
SYImagePicker.deleteCache();

android/src/main/java/com/syanpicker/RNSyanImagePickerModule.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
package com.syanpicker;
33

44
import android.app.Activity;
5+
import android.content.Context;
56
import android.content.Intent;
67
import android.graphics.BitmapFactory;
78
import android.text.TextUtils;
@@ -32,6 +33,7 @@
3233
import java.io.FileNotFoundException;
3334
import java.io.IOException;
3435
import java.io.InputStream;
36+
import java.text.DecimalFormat;
3537
import java.util.ArrayList;
3638
import java.util.List;
3739

@@ -279,13 +281,15 @@ private void openVideoPicker() {
279281
int MaxSecond = this.cameraOptions.getInt("MaxSecond");
280282
int MinSecond = this.cameraOptions.getInt("MinSecond");
281283
int recordVideoSecond = this.cameraOptions.getInt("recordVideoSecond");
282-
int videoCount = this.cameraOptions.getInt("videoCount");
284+
int videoCount = this.cameraOptions.getInt("imageCount");
285+
boolean isCamera = this.cameraOptions.getBoolean("allowTakeVideo");
286+
283287
Activity currentActivity = getCurrentActivity();
284288
PictureSelector.create(currentActivity)
285289
.openGallery(PictureMimeType.ofVideo())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
286290
.selectionMedia(selectList) // 当前已选中的视频 List
287291
.openClickSound(false)// 是否开启点击声音 true or false
288-
.isCamera(false)// 是否显示拍照按钮 true or false
292+
.isCamera(isCamera)// 是否显示拍照按钮 true or false
289293
.maxSelectNum(videoCount)// 最大视频选择数量 int
290294
.minSelectNum(1)// 最小选择数量 int
291295
.imageSpanCount(4)// 每行显示个数 int
@@ -330,12 +334,22 @@ private void onGetVideoResult(Intent data) {
330334
if (TextUtils.isEmpty(media.getPath())) {
331335
continue;
332336
}
337+
338+
DecimalFormat df = new DecimalFormat("#.00");
333339
WritableMap videoMap = new WritableNativeMap();
334-
videoMap.putString("size", new File(media.getPath()).length() + "");
335-
videoMap.putString("duration", media.getDuration() + "");
340+
341+
// File Path https://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore
342+
Context ctx = this.reactContext.getApplicationContext();
343+
String filePath = Utils.getPathFromURI(ctx, media.getPath());
344+
345+
videoMap.putString("uri", filePath);
336346
videoMap.putString("fileName", new File(media.getPath()).getName());
337-
videoMap.putString("uri", "file://" + media.getPath());
347+
videoMap.putDouble("size", new File(media.getPath()).length());
348+
videoMap.putDouble("duration", media.getDuration() / 1000.00);
349+
videoMap.putInt("width", media.getWidth());
350+
videoMap.putInt("height", media.getHeight());
338351
videoMap.putString("type", "video");
352+
videoMap.putString("mime", media.getMimeType());
339353
videoList.pushMap(videoMap);
340354
}
341355

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.syanpicker;
2+
3+
import android.content.Context;
4+
import android.database.Cursor;
5+
import android.net.Uri;
6+
import android.provider.MediaStore;
7+
8+
public class Utils {
9+
public static String getPathFromURI(Context context, String contentUri) {
10+
if (contentUri.indexOf("file://") > -1) {
11+
return contentUri;
12+
}
13+
14+
Cursor cursor = null;
15+
16+
try {
17+
String[] proj = {MediaStore.Images.Media.DATA};
18+
cursor = context.getContentResolver().query(Uri.parse(contentUri), proj, null, null, null);
19+
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
20+
cursor.moveToFirst();
21+
return cursor.getString(column_index);
22+
} finally {
23+
if (cursor != null) {
24+
cursor.close();
25+
}
26+
}
27+
}
28+
}

index.d.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ export interface ImagePickerOption {
2323
videoMaximumDuration: number, // 视频最大拍摄时间,默认是10分钟,单位是秒
2424
isWeChatStyle: boolean, // 是否是微信风格选择界面 Android Only
2525
sortAscendingByModificationDate: boolean // 对照片排序,按修改时间升序,默认是YES。如果设置为NO,最新的照片会显示在最前面,内部的拍照按钮会排在第一个
26+
videoCount: number // 视频个数
27+
MaxSecond: number // 选择视频最大时长,默认是180秒
28+
MinSecond: number // 选择视频最小时长,默认是1秒
2629
}
27-
30+
2831
interface SelectedPhoto {
2932
width: number, //图片宽度
3033
height: number, //图片高度
@@ -34,7 +37,7 @@ export interface ImagePickerOption {
3437
size:number, //图片大小,单位为字节 b
3538
base64:string //图片的 base64 编码,如果 enableBase64 设置 false,则不返回该属性
3639
}
37-
40+
3841
/**
3942
* 以Callback形式调用
4043
* 1、相册参数暂时只支持默认参数中罗列的属性;
@@ -54,8 +57,8 @@ export interface ImagePickerOption {
5457
* @param {Function} callback 成功,或失败回调
5558
*/
5659
export function showImagePicker (options:Partial<ImagePickerOption>,callback:(err:null|string,photos:Array<SelectedPhoto>)=>void): void;
57-
58-
60+
61+
5962
/**
6063
* 以Promise形式调用
6164
* 1、相册参数暂时只支持默认参数中罗列的属性;
@@ -83,33 +86,32 @@ export interface ImagePickerOption {
8386
* @return {Promise} 返回一个Promise对象
8487
*/
8588
export function asyncShowImagePicker (options:Partial<ImagePickerOption>): Promise<Array<SelectedPhoto>>;
86-
89+
8790
/**
8891
* 打开相机支持裁剪参数
8992
* @param options
9093
* @param callback
9194
*/
9295
export function openCamera (options:Partial<ImagePickerOption>,callback:(err:null|string,photos:Array<SelectedPhoto>)=>void): void;
93-
94-
96+
97+
9598
export function asyncOpenCamera (options:Partial<ImagePickerOption>): Promise<Array<SelectedPhoto>>;
96-
99+
97100
/**
98101
* 清除缓存
99102
*/
100103
export function deleteCache (): void;
101-
104+
102105
/**
103106
* 移除选中的图片
104107
* @param {Number} index 要移除的图片下标
105108
*/
106109
export function removePhotoAtIndex (index:number): void;
107-
110+
108111
/**
109112
* 移除所有选中图片
110113
*/
111114
export function removeAllPhoto (): void;
112-
115+
113116
export function openVideoPicker (options:Partial<ImagePickerOption>,callback:(err:null|string,photos:Array<SelectedPhoto>)=>void): void;
114-
115-
117+

index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,21 @@ export default {
140140
},
141141

142142
openVideoPicker(options, callback) {
143+
const imageCount = options.videoCount ? options.videoCount : 1
143144
const optionObj = {
144145
...defaultOptions,
145146
isCamera: false,
146147
allowPickingGif: false,
147148
allowPickingVideo: true,
148149
allowPickingImage: false,
149-
allowPickingMultipleVideo: true,
150+
allowTakeVideo: true,
151+
allowPickingMultipleVideo: imageCount > 1,
150152
videoMaximumDuration: 20,
151153
MaxSecond: 60,
152154
MinSecond: 0,
153155
recordVideoSecond: 60,
154-
videoCount: 1,
155-
...options
156+
...options,
157+
imageCount
156158
};
157159
return RNSyanImagePicker.openVideoPicker(optionObj, callback)
158160
}

ios/RNSyanImagePicker.m

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ - (void)openTZImagePicker:(NSDictionary *)options callback:(RCTResponseSenderBlo
114114
BOOL allowPickingVideo = [options sy_boolForKey:@"allowPickingVideo"];
115115
BOOL allowPickingMultipleVideo = [options sy_boolForKey:@"allowPickingMultipleVideo"];
116116
BOOL allowPickingImage = [options sy_boolForKey:@"allowPickingImage"];
117+
BOOL allowTakeVideo = [options sy_boolForKey:@"allowTakeVideo"];
117118
BOOL showCropCircle = [options sy_boolForKey:@"showCropCircle"];
118119
BOOL isRecordSelected = [options sy_boolForKey:@"isRecordSelected"];
119120
BOOL allowPickingOriginalPhoto = [options sy_boolForKey:@"allowPickingOriginalPhoto"];
@@ -131,9 +132,9 @@ - (void)openTZImagePicker:(NSDictionary *)options callback:(RCTResponseSenderBlo
131132
imagePickerVc.allowTakePicture = isCamera; // 允许用户在内部拍照
132133
imagePickerVc.allowPickingVideo = allowPickingVideo; // 不允许视频
133134
imagePickerVc.allowPickingImage = allowPickingImage;
134-
imagePickerVc.allowTakeVideo = NO;
135+
imagePickerVc.allowTakeVideo = allowTakeVideo; // 允许拍摄视频
135136
imagePickerVc.videoMaximumDuration = videoMaximumDuration;
136-
imagePickerVc.allowPickingMultipleVideo = isGif ? YES : allowPickingMultipleVideo;
137+
imagePickerVc.allowPickingMultipleVideo = isGif || allowPickingMultipleVideo ? YES : NO;
137138
imagePickerVc.allowPickingOriginalPhoto = allowPickingOriginalPhoto; // 允许原图
138139
imagePickerVc.sortAscendingByModificationDate = sortAscendingByModificationDate;
139140
imagePickerVc.alwaysEnableDoneBtn = YES;
@@ -176,6 +177,7 @@ - (void)openTZImagePicker:(NSDictionary *)options callback:(RCTResponseSenderBlo
176177
[imagePickerVc setDidFinishPickingVideoHandle:^(UIImage *coverImage, PHAsset *asset) {
177178
[weakPicker showProgressHUD];
178179
[[TZImageManager manager] getVideoOutputPathWithAsset:asset presetName:AVAssetExportPresetHighestQuality success:^(NSString *outputPath) {
180+
NSLog(@"视频导出成功:%@", outputPath);
179181
callback(@[[NSNull null], @[[self handleVideoData:outputPath asset:asset coverImage:coverImage quality:quality]]]);
180182
[weakPicker dismissViewControllerAnimated:YES completion:nil];
181183
[weakPicker hideProgressHUD];
@@ -518,12 +520,16 @@ - (NSDictionary *)handleVideoData:(NSString *)outputPath asset:(PHAsset *)asset
518520
video[@"fileName"] = [asset valueForKey:@"filename"];
519521
NSInteger size = [[NSFileManager defaultManager] attributesOfItemAtPath:outputPath error:nil].fileSize;
520522
video[@"size"] = @(size);
523+
video[@"duration"] = @(asset.duration);
521524
video[@"width"] = @(asset.pixelWidth);
522525
video[@"height"] = @(asset.pixelHeight);
526+
video[@"type"] = @"video";
527+
video[@"mime"] = @"video/mp4";
528+
// iOS only
529+
video[@"coverUri"] = [self handleCropImage:coverImage phAsset:asset quality:quality][@"uri"];
523530
video[@"favorite"] = @(asset.favorite);
524-
video[@"duration"] = @(asset.duration);
525531
video[@"mediaType"] = @(asset.mediaType);
526-
video[@"coverUri"] = [self handleCropImage:coverImage phAsset:asset quality:quality][@"uri"];
532+
527533
return video;
528534
}
529535

0 commit comments

Comments
 (0)