美文网首页
即时通讯_视频录制、播放

即时通讯_视频录制、播放

作者: 秋田之意 | 来源:发表于2016-06-22 19:00 被阅读119次

    这段时间做了OA管理类项目—IOS

    该项目主要模块分为:

    1、新闻、读报

    2、即时通讯、通讯录

    3、oa操作流程

    其中录制视频中遇到一些问题、接下来就简单总结一下。如果有代码问题希望大家及时提出,本人愿意虚心接受修改。希望能进步!

    @property(nonatomic,strong)AVCaptureMovieFileOutput *output;

    @property (nonatomic,strong) AVPlayer *player;//播放器对象;

    @property (nonatomic,strong) AVPlayerLayer * layer;

    @property(nonatomic,strong)NSString * uploadPath;//上传路径

    1、初始化

    //1.创建视频设备(摄像头前,后)

    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

    //2.初始化一个摄像头输入设备(first是后置摄像头,last是前置摄像头)

    AVCaptureDeviceInput *inputVideo = [AVCaptureDeviceInput deviceInputWithDevice:[devices firstObject] error:NULL];

    //3.创建麦克风设备

    AVCaptureDevice *deviceAudio = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];

    //4.初始化麦克风输入设备

    AVCaptureDeviceInput *inputAudio = [AVCaptureDeviceInput deviceInputWithDevice:deviceAudio error:NULL];

    //5.初始化一个movie的文件输出

    AVCaptureMovieFileOutput *output = [[AVCaptureMovieFileOutput alloc] init];

    self.output = output; //保存output

    //6.初始化一个会话

    AVCaptureSession *session = [[AVCaptureSession alloc] init];

    session.sessionPreset = AVCaptureSessionPreset640x480;

    //7.将输入输出设备添加到会话中

    if ([session canAddInput:inputVideo]) {

    [session addInput:inputVideo];

    }

    if ([session canAddInput:inputAudio]) {

    [session addInput:inputAudio];

    }

    if ([session canAddOutput:output]) {

    [session addOutput:output];

    }

    //8.创建一个预览涂层

    AVCaptureVideoPreviewLayer *preLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];

    preLayer.frame = self.view.frame;

    preLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    [self.view.layer addSublayer:preLayer];

    [session startRunning];

    2、录制完成转换为mp4

    - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error

    {

    NSLog(@"url === %@",outputFileURL);

    // 通过文件的 url 获取到这个文件的资源

    [self showHud];

    AVURLAsset *avAsset = [[AVURLAsset alloc] initWithURL:outputFileURL options:nil];

    // 用 AVAssetExportSession 这个类来导出资源中的属性

    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];

    // 压缩视频

    if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) { // 导出属性是否包含低分辨率

    // 通过资源(AVURLAsset)来定义 AVAssetExportSession,得到资源属性来重新打包资源 (AVURLAsset, 将某一些属性重新定义

    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];

    // 设置导出文件的存放路径

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

    [formatter setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];

    NSDate    *date = [[NSDate alloc] init];

    //存在临时temp

    NSString *outPutPath=[NSTemporaryDirectory() stringByAppendingString:[NSString stringWithFormat:@"myVideo%@.mp4",[formatter stringFromDate:date]]];

    NSURL * outUrl =[NSURL fileURLWithPath:outPutPath];

    exportSession.outputURL = outUrl;

    // 是否对网络进行优化

    exportSession.shouldOptimizeForNetworkUse = true;

    // 转换成MP4格式

    exportSession.outputFileType = AVFileTypeMPEG4;

    // 开始导出,导出后执行完成的block

    [exportSession exportAsynchronouslyWithCompletionHandler:^{

    [self hiddenHud];

    // 如果导出的状态为完成

    if ([exportSession status] == AVAssetExportSessionStatusCompleted) {

    dispatch_async(dispatch_get_main_queue(), ^{

    self.uploadPath = outPutPath;

    //完成录制、开始播放

    [self initPlayer:outPutPath];

    });

    }else if ([exportSession status]==AVAssetExportSessionStatusFailed){

    NSLog(@"mp4 export Fail!");

    }else if ([exportSession status] == AVAssetExportSessionStatusWaiting){

    NSLog(@"wait");

    }

    }];

    }

    3、播放视频

    #pragma mark -播放视频

    - (void)initPlayer:(NSString *)path

    {

    NSURL *  url= [NSURL fileURLWithPath:path];

    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];

    _player = [AVPlayer playerWithPlayerItem:item];

    _layer = [AVPlayerLayer playerLayerWithPlayer:_player];

    _layer.frame = CGRectMake(0, 64, self.view.layer.bounds.size.width, 300*SCREEN_WIDTHSCALE);

    _layer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    // 显示播放视频的视图层要添加到self.view的视图层上面

    [self.view.layer addSublayer:_layer];

    [_player play];

    [self addNotification];

    }

    4、 循环播放-添加通知监听

    -(void)addNotification{

    //给AVPlayerItem添加播放完成通知

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];

    }

    - (void)playbackFinished:(NSNotification *)notification

    {

    // 播放完成后重复播放

    // 跳到最新的时间点开始播放

    [_player seekToTime:CMTimeMake(0, 1)];

    [_player play];

    }

    -(void)dealloc

    {

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    }

    5、缩略图

    #pragma mark - 缩略图

    - (UIImage *)getImage:(NSString *)videoURL

    {

    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:videoURL] options:nil];

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

    gen.appliesPreferredTrackTransform = YES;

    CMTime time = CMTimeMakeWithSeconds(0.0, 600);

    NSError *error = nil;

    CMTime actualTime;

    CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];

    UIImage *thumb = [[UIImage alloc] initWithCGImage:image];

    CGImageRelease(image);

    return thumb;

    }

    6、注释

      1、如果项目还有android端,在android端录制的时候 把编码格式设置为AAC,否则android录制出来之后在ios端播放不了。

    2、在ios9可以使用 AVPlayerViewController进行播放、同时MPMoviePlayerController即将被弃用。

    3、小视频录制最重要的其实是视频质量和大小的压缩和处理。这点我还在学习中...如果哪个朋友有相关的参考资料希望可以分享给我.谢谢。

    相关文章

      网友评论

          本文标题:即时通讯_视频录制、播放

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