美文网首页
iOS---视频播放、剪切、暂停

iOS---视频播放、剪切、暂停

作者: 彬至睢阳 | 来源:发表于2019-05-18 17:03 被阅读0次

    #import "TVViewController.h"

    #import<AVFoundation/AVFoundation.h>

    #import<MediaPlayer/MediaPlayer.h>

    @interface TVViewController ()<UIScrollViewDelegate>

    {

        BOOLplayToEndTimeBool;//是否播放结束

    }

    @property(nonatomic,strong)AVPlayer* payerTV;

    @property(nonatomic,strong)AVPlayerItem* playAtem;

    @property(nonatomic,strong)UIView* loadProgressView;

    @property(nonatomic,strong)UILabel* totalTimeLab;

    @property(nonatomic,strong)AVPlayerLayer* playerLayer;

    @property(nonatomic,strong)NSURL* url;

    @property(nonatomic,strong)UILabel* currentTimeLab;

    @property(nonatomic,strong)NSMutableArray* timeMutArr;

    @property(nonatomic,strong)UIScrollView*editScrollView;

    @property(nonatomic,strong)NSString* tempPath;

    @end

    @implementationTVViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        [self initInterface];

        [selfinitTV];

    }

    #pragma mark----视屏的初始化

    - (void)initTV{

        [self addPlayer];

        [selfaddBut];

    }

    #pragma mark----添加播放器

    - (void)addPlayer{

        playToEndTimeBool = NO;//默认没有播放结束

         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PlayToEndTime) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];

        self.url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"tv" ofType:@"mp4"]];

        self.playAtem = [AVPlayerItem playerItemWithURL:self.url];

        //self.playAtem.asset

        self.payerTV = [[AVPlayer alloc]initWithPlayerItem:_playAtem];

        //创建播放器

        self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.payerTV];

        self.playerLayer.frame = CGRectMake(0, 160,  [UIScreen mainScreen].bounds.size.width,  140);

        [self.view.layer addSublayer:self.playerLayer];

    //    [self.payerTV seekToTime:CMTimeMakeWithSeconds(0, 1000)];//设置播放位置  1000位帧率

         [self.payerTV seekToTime:CMTimeMake(0, 1)];

        /*volume--表示当前播放器的音频音量;0.0表示“关闭所有音频”,1.0表示“以当前项的最大音量播放”。

         iOS注意:不要使用此属性实现用于媒体播放的音量滑块。为此,使用MPVolumeView,它在外观上是可定制的,并提供用户期望的标准媒体播放行为。

         这个属性在iOS中最有用的是控制AVPlayer相对于其他音频输出的音量,而不是最终用户的音量控制。*/

        self.payerTV.volume=0.5;

        UIProgressView* progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];

        progressView.frame = CGRectMake(0, 150, [UIScreen mainScreen].bounds.size.width, 20);

        [self.viewaddSubview:progressView];

        self.loadProgressView = [[UIView alloc]initWithFrame:CGRectMake(0, 145, 10, 10)];

        [self.view addSubview:self.loadProgressView];

        self.loadProgressView.backgroundColor = [UIColor yellowColor];

        __weak typeof(self)WeakSelf = self;

       //监听视频播放进度

        [self.payerTV addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC) queue:NULL usingBlock:^(CMTime time) {

             __strongtypeof(WeakSelf) strongSelf = WeakSelf;

            //进度 当前时间/总时间

            CGFloat progress = CMTimeGetSeconds(strongSelf.payerTV.currentItem.currentTime) / CMTimeGetSeconds(strongSelf.payerTV.currentItem.duration);

            progressView.progress= progress;

             strongSelf.currentTimeLab.text = [NSString stringWithFormat:@"播放视频时长%f秒", CMTimeGetSeconds(strongSelf.payerTV.currentItem.currentTime)];

            //CGSize size = strongSelf.playAtem.presentationSize;//获取视频的大小

            if(progress ==1) {

                //防止当进度为1时,loadProgressView在视图上消失

                 strongSelf.loadProgressView.frame=CGRectMake(progress*[UIScreenmainScreen].bounds.size.width-10,145,10,10);

            }else{

                 strongSelf.loadProgressView.frame=CGRectMake(progress*[UIScreenmainScreen].bounds.size.width,145,10,10);

            }

        }];

        //在进度条上面--添加手势--可以拖动控制播放的位置

        UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureRecognizer:)];

        [self.loadProgressView addGestureRecognizer:pan];

        [self AVAssetImageGenerator];

    }

    #pragma mark---获取视频帧图像

    -(void)AVAssetImageGenerator{

        /*

        AVAssetImageGenerator 提供独立于回放的资产的缩略图或预览图像的对象。

         */

        self.editScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 300, [UIScreen mainScreen].bounds.size.width, 80)];

        [self.view addSubview:self.editScrollView];

        self.editScrollView.delegate = self;

    //读取解析视频帧

        //初始化AVURLAsset对象

        AVURLAsset* asset = [[AVURLAsset alloc]initWithURL:self.url options:nil];

        //获取总视频的长度 = 总帧数 / 每秒的帧数

        longsumTime = asset.duration.value/ asset.duration.timescale;

        //创建AVAssetImageGenerator对象

        AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc]initWithAsset:asset];

        generator.maximumSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 80);

        generator.appliesPreferredTrackTransform = YES;

        generator.requestedTimeToleranceBefore = kCMTimeZero;

        generator.requestedTimeToleranceAfter = kCMTimeZero;

        // 添加需要帧数的时间集合

        self.timeMutArr = [NSMutableArray array];

        for(inti =0; i < sumTime; i++) {

            CMTime time = CMTimeMake(i *asset.duration.timescale , asset.duration.timescale);

            NSValue *value = [NSValue valueWithCMTime:time];

            [self.timeMutArraddObject:value];

        }

        __blocklongcount =0;

        [generatorgenerateCGImagesAsynchronouslyForTimes:self.timeMutArr completionHandler:^(CMTime requestedTime, CGImageRef img, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){

            if (result == AVAssetImageGeneratorSucceeded) {

                    NSLog(@"%ld",count);

                    dispatch_sync(dispatch_get_main_queue(), ^{

                        UIImageView*thumImgView = [[UIImageViewalloc]init];

                        thumImgView.image= [UIImageimageWithCGImage:img];

                        [self.editScrollViewaddSubview:thumImgView];

                        thumImgView.frame=CGRectMake(50+count*50,0,50,70);

                        self.editScrollView.contentSize=CGSizeMake(100+count*50,0);

                    });

                     count++;

            }

            if (result == AVAssetImageGeneratorFailed) {

                NSLog(@"Failed with error: %@", [error localizedDescription]);

            }

            if (result == AVAssetImageGeneratorCancelled) {

                NSLog(@"AVAssetImageGeneratorCancelled");

            }

        }];

       [self.editScrollView setContentOffset:CGPointMake(50, 0)];

    }

    - (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate{

        NSLog(@"%f",scrollView.contentOffset.x);

         NSLog(@"%f",scrollView.contentSize.width);

         NSLog(@"%f",scrollView.contentSize.width);

        CGFloatprogress = scrollView.contentOffset.x/scrollView.contentSize.width;

         self.loadProgressView.frame = CGRectMake(progress*[UIScreen mainScreen].bounds.size.width, 145, 10, 10);

    }

    #pragma mark---视频裁剪

    - (void)deleteTv{

        self.tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmpMov.mp4"];

         [self deleteTempFile];//视频裁剪的时候要清理一下之前的视屏

        AVAsset *asset = [AVAsset assetWithURL:self.url];

        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]

                                               initWithAsset:asset presetName:AVAssetExportPresetPassthrough];

        NSURL *furl = [NSURL fileURLWithPath:self.tempPath];

        exportSession.outputURL= furl;//

        exportSession.outputFileType = AVFileTypeMPEG4;

      NSInteger startTime =  CMTimeGetSeconds(self.payerTV.currentItem.currentTime);//希望剪切的---开始时间点

         NSInteger endTime = CMTimeGetSeconds(self.payerTV.currentItem.duration);//希望剪切的---结束时间点

        CMTime start = CMTimeMakeWithSeconds(startTime, CMTimeGetSeconds(self.playAtem.duration));

        CMTime duration = CMTimeMakeWithSeconds(endTime - startTime, CMTimeGetSeconds(self.payerTV.currentItem.duration));

        CMTimeRangerange =CMTimeRangeMake(start, duration);

        exportSession.timeRange= range;

        [exportSessionexportAsynchronouslyWithCompletionHandler:^{

            switch([exportSessionstatus]) {

                case AVAssetExportSessionStatusFailed:

                    NSLog(@"Export failed: %@", [[exportSessionerror]localizedDescription]);

                    break;

                case AVAssetExportSessionStatusCancelled:

                    NSLog(@"Export canceled");

                    break;

                default:

                    NSLog(@"NONE");

                    NSURL*movieUrl = [NSURLfileURLWithPath:self.tempPath];

                    dispatch_sync(dispatch_get_main_queue(), ^{

                      UISaveVideoAtPathToSavedPhotosAlbum([movieUrlrelativePath],self,@selector(video:didFinishSavingWithError:contextInfo:),nil);

                        NSLog(@"编辑后的视频路径: %@",self.tempPath);

                    });

                    break;

            }

        }];

    }

    - (void)video:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo {

        if(error) {

            NSLog(@"保存到相册失败");

        }else{

            NSLog(@"保存到相册成功");

        }

    }

    -(void)addBut{

        UIButton* playBut = [UIButton buttonWithType:UIButtonTypeCustom];

        [self.viewaddSubview:playBut];

        playBut.frame=CGRectMake(20,104,80,30);

        [playButsetTitle:@"播放" forState:UIControlStateNormal];

        [playButsetTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

        [playButaddTarget:self action:@selector(play) forControlEvents:UIControlEventTouchUpInside];

        playBut.titleLabel.font = [UIFont systemFontOfSize:16.0f];

        UIButton* suspendedBut = [UIButton buttonWithType:UIButtonTypeCustom];

        [self.viewaddSubview:suspendedBut];

        suspendedBut.frame=CGRectMake(120,104,80,30);

        [suspendedButsetTitle:@"暂停" forState:UIControlStateNormal];

        [suspendedButsetTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

        [suspendedButaddTarget:self action:@selector(suspended) forControlEvents:UIControlEventTouchUpInside];

        suspendedBut.titleLabel.font = [UIFont systemFontOfSize:16.0f];

        UIButton* forwardBut = [UIButton buttonWithType:UIButtonTypeCustom];

        [self.viewaddSubview:forwardBut];

        forwardBut.frame=CGRectMake(120,64,80,30);

        [forwardButsetTitle:@"前进" forState:UIControlStateNormal];

        [forwardButsetTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

        [forwardButaddTarget:self action:@selector(forward) forControlEvents:UIControlEventTouchUpInside];

        forwardBut.titleLabel.font = [UIFont systemFontOfSize:16.0f];

        UIButton* retBut = [UIButton buttonWithType:UIButtonTypeCustom];

        [self.viewaddSubview:retBut];

        retBut.frame=CGRectMake(220,104,80,30);

        [retButsetTitle:@"重播" forState:UIControlStateNormal];

        [retButsetTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

        [retButaddTarget:self action:@selector(ret) forControlEvents:UIControlEventTouchUpInside];

        retBut.titleLabel.font = [UIFont systemFontOfSize:16.0f];

        UIButton* backBut = [UIButton buttonWithType:UIButtonTypeCustom];

        [self.viewaddSubview:backBut];

        backBut.frame=CGRectMake(220,64,80,30);

        [backButsetTitle:@"后退" forState:UIControlStateNormal];

        [backButsetTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

        [backButaddTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];

        backBut.titleLabel.font = [UIFont systemFontOfSize:16.0f];

        self.totalTimeLab = [[UILabel alloc]initWithFrame:CGRectMake(10, 190, 280, 30)];

        [self.view addSubview:self.totalTimeLab];

        self.totalTimeLab.textColor = [UIColor blackColor];

        self.totalTimeLab.font = [UIFont systemFontOfSize:14.0f];

        self.currentTimeLab = [[UILabel alloc]initWithFrame:CGRectMake(10, 160, 280, 30)];

        [self.view addSubview:self.currentTimeLab];

        self.currentTimeLab.textColor = [UIColor blackColor];

        self.currentTimeLab.font = [UIFont systemFontOfSize:14.0f];

    }

    #pragma mark---

    - (void)panGestureRecognizer:(UIPanGestureRecognizer*)pan{

        //获取手势的位置

        CGPointposition =[pantranslationInView:self.loadProgressView];

        //通过stransform 进行平移交换

        self.loadProgressView.transform = CGAffineTransformTranslate(self.loadProgressView.transform, position.x, position.y);

        //将增量置为零

        [pansetTranslation:CGPointZero inView:self.loadProgressView];

        CGFloat progress = self.loadProgressView.frame.origin.x/[UIScreen mainScreen].bounds.size.width;

       [self.payerTV seekToTime:CMTimeMakeWithSeconds(CMTimeGetSeconds(self.payerTV.currentItem.duration)*progress, 1000)];//设置播放位置  1000位帧率

         [self.payerTVplay];

    }

    #pragma mark----重播

    -(void)ret{

    //  [self.payerTV seekToTime:CMTimeMakeWithSeconds(0, 1000)];//设置播放位置  1000位帧率

    //  [self.payerTV play];

        //播放剪切之后的视屏

        self.url= [NSURL fileURLWithPath:self.tempPath];

        self.playAtem = [AVPlayerItem playerItemWithURL:self.url];

        self.payerTV = [[AVPlayer alloc]initWithPlayerItem:_playAtem];

        //创建播放器

        self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.payerTV];

        self.playerLayer.frame = CGRectMake(0, 160,  [UIScreen mainScreen].bounds.size.width,  140);

        [self.view.layer addSublayer:self.playerLayer];

        [self.payerTV seekToTime:CMTimeMakeWithSeconds(0, 1000)];//设置播放位置  1000位帧率

         [self.payerTVplay];

    }

    #pragma mark--视屏后退

    -(void)back{

    //    CGFloat currentTime= CMTimeGetSeconds(self.payerTV.currentItem.currentTime);

    //    if (currentTime>2) {

    //        [self.payerTV seekToTime:CMTimeMakeWithSeconds(currentTime-2, 1000)];//设置播放位置  1000位帧率

    //    }

         [selfdeleteTv];

    }

    #pragma mark--视屏前进

    -(void)forward{

        CGFloat currentTime= CMTimeGetSeconds(self.payerTV.currentItem.currentTime);

        CGFloat totalTime = CMTimeGetSeconds(self.payerTV.currentItem.duration);

        if((totalTime-currentTime)>2) {

            [self.payerTV seekToTime:CMTimeMakeWithSeconds(CMTimeGetSeconds(self.payerTV.currentItem.currentTime)+2, 1000)];//设置播放位置  1000位帧率

        }

    }

    #pragma mark----播放结束

    -(void)PlayToEndTime{

        playToEndTimeBool = YES;//播放结束

    }

    #pragma mark---播放

    -(void)play{

    //    CMTime time = _payerTV.currentItem.duration;//当前播放对象的持续时间总长

    //    CMTime currentTime =_payerTV.currentTime;//当前播放对象的播放位置

    //    if (time.timescale == currentTime.timescale) {//当播放结束的时候,重新从头播放

    //        [self.payerTV seekToTime:CMTimeMakeWithSeconds(0, 1000)];//设置播放位置  1000位帧率

    //    }

        if (playToEndTimeBool) {

            playToEndTimeBool = NO;

             [self.payerTV seekToTime:CMTimeMakeWithSeconds(0, 1000)];//设置播放位置  1000位帧率

        }

         [self.payerTVplay];

        self.totalTimeLab.text= [NSStringstringWithFormat:@"播放视频总时长%ff秒",CMTimeGetSeconds(self.payerTV.currentItem.duration)];

    }

    - (void)deleteTempFile{

        NSURL *url = [NSURL fileURLWithPath:self.tempPath];

        NSFileManager *fm = [NSFileManager defaultManager];

        BOOLexist = [fmfileExistsAtPath:url.path];

        NSError*err;

        if(exist) {

            [fmremoveItemAtURL:urlerror:&err];

        }else{

        }

    }

    #pragma mark---暂停

    -(void)suspended{

        [self.payerTVpause];

    }

    - (void)dealloc{

        self.payerTV  =nil;

    }

    #pragma mark--界面初始化

    - (void)initInterface{

        self.view.backgroundColor = [UIColor whiteColor];

        self.title = @"视屏的播放与截取";

    }

    @end

    相关文章

      网友评论

          本文标题:iOS---视频播放、剪切、暂停

          本文链接:https://www.haomeiwen.com/subject/uvbtzqtx.html