1. 程式人生 > 其它 >IOS之Tok Tik(部分實現)

IOS之Tok Tik(部分實現)

IOS之Tok Tik

個人貢獻

完成釋出廣場頁面,實現視訊的選取、編輯(裁剪、加速、放慢)、以及需求分析與設計文件

程式碼與截圖

釋出廣場

- (void)viewDidLoad {
    [super viewDidLoad];
        _videoBox = [WAVideoBox new];
    _finalvideo = [[NSString alloc] init];
    _finalpic = [[NSString alloc] init];
    _finaltitle =
[[NSString alloc] init]; _finalimage = [[UIImage alloc] init]; _rate = 1; self.view.backgroundColor = [UIColor colorWithRed:242.0/255 green:242.0/255 blue:247.0/255 alpha:1]; self.title = @"釋出廣場"; UIBarButtonItem *rightBarItem = [[UIBarButtonItem alloc] initWithTitle:
@"釋出" style:UIBarButtonItemStylePlain target:self action:@selector(onClickedOKbtn)]; self.navigationItem.rightBarButtonItem = rightBarItem; //NSLog(@"%@",_videoPath); self.edgesForExtendedLayout = UIRectEdgeBottom; _Titile = [[UITextField alloc]
init]; [self.view addSubview:_Titile]; [_Titile mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.view.mas_top).with.offset(self.view.frame.size.width*0.1); make.centerX.equalTo(self.view); make.width.equalTo(self.view.mas_width).multipliedBy(0.8); make.height.equalTo(self.view.mas_width).multipliedBy(0.12); }]; [_Titile setFont:[UIFont systemFontOfSize:25]]; _Titile.placeholder = @"請輸入標題"; _Titile.layer.borderColor = [[UIColor blackColor] CGColor]; _Titile.layer.borderWidth = 1; _Titile.layer.cornerRadius = 5; _Titile.textAlignment = NSTextAlignmentCenter; _add = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self.view addSubview:_add]; [_add mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_Titile.mas_bottom).with.offset(self.view.frame.size.width*0.03); make.centerX.equalTo(self.view); make.width.equalTo(self.view.mas_width).multipliedBy(0.3); make.height.equalTo(self.view.mas_width).multipliedBy(0.1); }]; [_add setTitle:@"上傳視訊" forState:UIControlStateNormal]; [_add addTarget:self action:@selector(clickpicView:) forControlEvents:UIControlEventTouchUpInside]; // [_add setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; _add.titleLabel.font = [UIFont systemFontOfSize:15]; // _add.layer.borderColor = [[UIColor blackColor] CGColor]; // _add.layer.borderWidth = 1; _imageView = [[UIImageView alloc] init]; [self.view addSubview:_imageView]; [_imageView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(self.view.mas_width).with.offset(-10); make.height.equalTo(self.view.mas_width).with.offset(-10); make.top.equalTo(_add.mas_bottom).with.offset(self.view.frame.size.width*0.05); make.centerX.equalTo(self.view); }]; // _imageView.layer.borderColor = [[UIColor blackColor] CGColor]; // _imageView.layer.borderWidth = 1; _back = [[UIImageView alloc] init]; [self.view addSubview:_back]; [_back mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(self.view.mas_width).multipliedBy(0.95); make.height.equalTo(self.view.mas_height).multipliedBy(0.78); make.top.equalTo(_add.mas_bottom).with.offset(self.view.frame.size.width*0.03); make.centerX.equalTo(self.view); }]; // _back.layer.borderColor = [[UIColor blackColor] CGColor]; // _back.layer.borderWidth = 1; _cut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self.view addSubview:_cut]; [_cut mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_imageView.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(self.view.mas_left).with.offset(self.view.frame.size.width*0.1); make.width.equalTo(self.view.mas_width).multipliedBy(0.18); make.height.equalTo(self.view.mas_width).multipliedBy(0.11); }]; _back.image = [UIImage imageNamed:@"3"]; [_cut addTarget:self action:@selector(rangeVideo:) forControlEvents:UIControlEventTouchUpInside]; _cut.titleLabel.font = [UIFont systemFontOfSize:20]; _cut.layer.cornerRadius = 5; _s = [[UITextField alloc] init]; _e = [[UITextField alloc] init]; [self.view addSubview:_s]; [self.view addSubview:_e]; [_s mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_imageView.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(_cut.mas_right).with.offset(15); make.width.equalTo(self.view.mas_width).multipliedBy(0.08); make.height.equalTo(self.view.mas_width).multipliedBy(0.1); }]; [_e mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_imageView.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(_s.mas_right).with.offset(30); make.width.equalTo(self.view.mas_width).multipliedBy(0.08); make.height.equalTo(self.view.mas_width).multipliedBy(0.1); }]; _s.layer.backgroundColor = [[UIColor clearColor] CGColor]; _e.layer.backgroundColor = [[UIColor clearColor] CGColor]; _s.delegate = self; _e.delegate = self; _s.textAlignment = NSTextAlignmentRight; [_s setFont:[UIFont systemFontOfSize:25]]; [_e setFont:[UIFont systemFontOfSize:25]]; _dot = [[UILabel alloc] init]; [self.view addSubview:_dot]; [_dot mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_imageView.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(_s.mas_right).with.offset(0); make.width.mas_equalTo(30); make.height.equalTo(self.view.mas_width).multipliedBy(0.1); }]; [_dot setFont:[UIFont fontWithName:@"Helvetica-Bold" size:22]]; _dot.textAlignment = NSTextAlignmentCenter; _logo = [[UIImageView alloc] init]; [self.view addSubview:_logo]; [_logo mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(100); make.height.mas_equalTo(100); make.top.equalTo(_imageView.mas_bottom).with.offset(self.view.frame.size.width*0.05); make.left.equalTo(self.view.mas_left).with.offset(self.view.frame.size.width*0.7); }]; UIImage * icon = [UIImage imageNamed:@"1"]; CGSize itemSize = CGSizeMake(100, 100);//固定圖片大小為36*36 UIGraphicsBeginImageContextWithOptions(itemSize, NO, 0.0);//*1 CGRect imageRect = CGRectMake(0, 0, itemSize.width, itemSize.height); [icon drawInRect:imageRect]; _fast = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self.view addSubview:_fast]; [_fast mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_cut.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(self.view.mas_left).with.offset(self.view.frame.size.width*0.1); make.width.equalTo(self.view.mas_width).multipliedBy(0.18); make.height.equalTo(self.view.mas_width).multipliedBy(0.11); }]; [_fast addTarget:self action:@selector(gearVideo:) forControlEvents:UIControlEventTouchUpInside]; _fast.titleLabel.font = [UIFont systemFontOfSize:20]; _fast.layer.cornerRadius = 5; _slow = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self.view addSubview:_slow]; [_slow mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_cut.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(_fast.mas_right).with.offset(self.view.frame.size.width*0.1); make.width.equalTo(self.view.mas_width).multipliedBy(0.18); make.height.equalTo(self.view.mas_width).multipliedBy(0.11); }]; [_slow addTarget:self action:@selector(slowVideo:) forControlEvents:UIControlEventTouchUpInside]; _slow.titleLabel.font = [UIFont systemFontOfSize:20]; _slow.layer.cornerRadius = 5; _v = [[UILabel alloc] init]; [self.view addSubview:_v]; [_v mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_cut.mas_bottom).with.offset(self.view.frame.size.width*0.1); make.left.equalTo(_slow.mas_right).with.offset(self.view.frame.size.width*0.1); make.width.equalTo(self.view.mas_width).multipliedBy(0.2); make.height.equalTo(self.view.mas_width).multipliedBy(0.1); }]; _v.layer.backgroundColor = [[UIColor clearColor] CGColor]; [_v setFont:[UIFont systemFontOfSize:25]]; // _combine = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // [self.view addSubview:_combine]; // [_combine mas_makeConstraints:^(MASConstraintMaker *make) { // make.top.equalTo(_cut.mas_bottom).with.offset(self.view.frame.size.width*0.1); // make.left.equalTo(self.view.mas_left).with.offset(self.view.frame.size.width*0.1); // make.width.equalTo(self.view.mas_width).multipliedBy(0.1); // make.height.equalTo(self.view.mas_width).multipliedBy(0.1); // }]; // [_combine setTitle:@"拼接" forState:UIControlStateNormal]; // [_combine addTarget:self action:@selector(gearVideo:) forControlEvents:UIControlEventTouchUpInside]; // _combine.titleLabel.font = [UIFont systemFontOfSize:20]; }

在這裡插入圖片描述
在這裡插入圖片描述

選取視訊

-(void)clickpicView:(UIButton *)btn
{
    UIImagePickerController * picker = [[UIImagePickerController alloc]init];
    NSString *requiredMediaType1 = ( NSString *)kUTTypeMovie;

        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

        //UIImagePickerControllerSourceTypeSavedPhotosAlbum

        NSArray *arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType1,nil];

        [picker setMediaTypes: arrMediaTypes];

    picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
    

}

- (void)pickerControllerDidCancel:(DLPhotoPickerViewController *)picker
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    [picker dismissViewControllerAnimated:YES completion:nil];
       //info中就是包含你在相簿裡面選擇的圖片
    NSURL * localurltemp = info[@"UIImagePickerControllerMediaURL"];
    
    //NSURL *URL = [NSURL URLWithString:localurltemp];  /ring>url
    NSString *str1 = [localurltemp absoluteString];//url>string
    NSString * str2 = [str1 substringFromIndex:7];
    _videoPath = str2;
    _finalvideo = str2;
    NSURL * temp2 = [[NSURL alloc] initWithString:str2];
    //拿到圖片會就銷燬之前的控制器
    NSTimeInterval t = (NSTimeInterval)1;
    UIImage *icon = [self thumbnailImageForVideo:localurltemp atTime:(t)];
    _finalimage = icon;
    CGSize itemSize = CGSizeMake(self.view.frame.size.width-10, self.view.frame.size.width-10);//固定圖片大小為50*50
    UIGraphicsBeginImageContextWithOptions(itemSize, NO, 0.0);//*1
    CGRect imageRect = CGRectMake(0, 0, itemSize.width, itemSize.height);
    [icon drawInRect:imageRect];
    _imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    _size = [self getVideoInfoWithSourcePath:_videoPath];
    NSString *tem = [NSString stringWithFormat:@"%@",_size[@"duration"]];
    _s.text = @"0";
    _e.text = tem;

    _dot.text = @":";
    NSString *str = [NSString stringWithFormat:@" X%.1f",_rate];
    _v.text = str;

    _logo.image = UIGraphicsGetImageFromCurrentImageContext();//*2
    UIGraphicsEndImageContext();//*3

    [_cut setTitle:@"裁剪" forState:UIControlStateNormal];
    _cut.layer.borderWidth = 1;
    _cut.layer.borderColor = [[UIColor grayColor] CGColor];

    [_fast setTitle:@"加速" forState:UIControlStateNormal];
    _fast.layer.borderWidth = 1;
    _fast.layer.borderColor = [[UIColor grayColor] CGColor];

    [_slow setTitle:@"減速" forState:UIControlStateNormal];
    _slow.layer.borderWidth = 1;
    _slow.layer.borderColor = [[UIColor grayColor] CGColor];

    _back.image = [UIImage imageNamed:@""];

    
}

在這裡插入圖片描述

視訊編輯

建立編輯後視訊的儲存路徑

-(NSString *)buildFilePath{
    
    return [NSTemporaryDirectory() stringByAppendingString:[NSString stringWithFormat:@"%f.mp4", [[NSDate date] timeIntervalSinceReferenceDate]]];
}
- (void)goToPlayVideoByFilePath:(NSString *)filePath{
    PlayViewController *playVc = [PlayViewController new];
    [playVc loadWithFilePath:filePath];
    [self.navigationController pushViewController:playVc animated:YES];
}

視訊裁剪

- (IBAction)rangeVideo:(id)sender {
    
    [_videoBox clean];
    NSString *filePath = [self buildFilePath];
    __weak typeof(self) wself = self;
//    NSLog(@"%@",_videoPath);
    [_videoBox appendVideoByPath:_videoPath];
    
    int64_t ss = [_s.text intValue];
    int64_t ee = [_e.text intValue];
    [_videoBox rangeVideoByTimeRange:CMTimeRangeMake(CMTimeMake(ss*60, 60), CMTimeMake(ee*60, 60))];
    [_videoBox gearBoxWithScale:_rate];
    [_videoBox asyncFinishEditByFilePath:filePath complete:^(NSError *error) {
        if (!error) {
            [wself goToPlayVideoByFilePath:filePath];
        }
    }];
    _Path = filePath;
}

在這裡插入圖片描述
視訊加速

- (IBAction)gearVideo:(id)sender {
    _rate += 0.5;
//    NSLog(@"%f",_rate);
    NSString *str = [NSString stringWithFormat:@" X%.1f",_rate];
    _v.text = str;
    [_videoBox clean];
    NSString *filePath = [self buildFilePath];
    __weak typeof(self) wself = self;
    
    [_videoBox appendVideoByPath:_videoPath];
    int64_t ss = [_s.text intValue];
    int64_t ee = [_e.text intValue];
    [_videoBox rangeVideoByTimeRange:CMTimeRangeMake(CMTimeMake(ss*60, 60), CMTimeMake(ee*60, 60))];
    [_videoBox gearBoxWithScale:_rate];
    
    [_videoBox asyncFinishEditByFilePath:filePath complete:^(NSError *error) {
        if (!error) {
            [wself goToPlayVideoByFilePath:filePath];
        }
    }];
    _Path = filePath;
}

視訊放慢

- (IBAction)slowVideo:(id)sender {
    _rate -= 0.5;
//    NSLog(@"%f",_rate);
    NSString *str = [NSString stringWithFormat:@" X%.1f",_rate];
    _v.text = str;
    [_videoBox clean];
    NSString *filePath = [self buildFilePath];
    __weak typeof(self) wself = self;
    
    [_videoBox appendVideoByPath:_videoPath];
    int64_t ss = [_s.text intValue];
    int64_t ee = [_e.text intValue];
    [_videoBox rangeVideoByTimeRange:CMTimeRangeMake(CMTimeMake(ss*60, 60), CMTimeMake(ee*60, 60))];
    [_videoBox gearBoxWithScale:_rate];
    
    [_videoBox asyncFinishEditByFilePath:filePath complete:^(NSError *error) {
        if (!error) {
            [wself goToPlayVideoByFilePath:filePath];
        }
    }];
    _Path = filePath;
}

獲取視訊的長度

- (NSDictionary *)getVideoInfoWithSourcePath:(NSString *)path{
    AVURLAsset * asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];
    CMTime   time = [asset duration];
    int seconds = ceil(time.value/time.timescale);

    NSInteger   fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize;

    return @{@"size" : @(fileSize),
             @"duration" : @(seconds)};
}

在這裡插入圖片描述

問題與解決方法

問題

  1. 使用DLPhotoPicker庫時不能得到選取視訊的地址
  2. 選取視訊後的封面選取

解決方法

  1. 使用IOS自帶的系統相簿庫
    之前使用DLPhotoPicker庫
-(void)buttonClicked:(id)sender{
    
    DLPhotoPickerViewController *picker = [[DLPhotoPickerViewController alloc] init];
    picker.delegate = self;
    picker.pickerType = DLPhotoPickerTypePicker;
    picker.navigationTitle = NSLocalizedString(@"相簿", nil);
    [self presentViewController:picker animated:YES completion:nil];
    
    
}

使用IOS自帶的庫

-(void)clickpicView:(UIButton *)btn
{
    UIImagePickerController * picker = [[UIImagePickerController alloc]init];
    NSString *requiredMediaType1 = ( NSString *)kUTTypeMovie;

        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

        //UIImagePickerControllerSourceTypeSavedPhotosAlbum

        NSArray *arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType1,nil];

        [picker setMediaTypes: arrMediaTypes];

    picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
    

}
  1. 在選取的視訊中選取一秒時候的圖片作為封面
-(UIImage*) thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
    NSParameterAssert(asset);
    AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
    assetImageGenerator.appliesPreferredTrackTransform = YES;
    assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
    CGImageRef thumbnailImageRef = NULL;
    CFTimeInterval thumbnailImageTime = time;
    NSError *thumbnailImageGenerationError = nil;
    thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
    if(!thumbnailImageRef)
        NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
    UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
    return thumbnailImage;
}

個人總結

這次實驗主要是完成視訊的選取以及編輯,這讓我對於IOS的視訊運用更加了解和熟悉,特別是視訊的編輯,雖然是引用了別人寫好的庫,但是在學習使用的過程中從原始碼中學到了很多,比如儲存路徑的建立、視訊播放等。
個人貢獻評分 90

思想感悟

這次遇到的最大問題是在使用DLPhotoPicker庫時單個頁面執行是可以的,但是當整個專案合起來時就不行了,不能獲取選取視訊的地址,在網上查找了很久都沒有解決辦法,最後只能運用系統的庫。這告訴我們雖然第三方寫的庫可能更加方便,但是可能存在一些bug或者使用的難度,有些時候迴歸系統自帶的庫可能更容易解決問題。