音视频

作者: block_smile | 来源:发表于2017-05-31 10:07 被阅读18次

音效

  • 1.iOS中音乐可以暂停,音效不能操作;而且音效可以立即播放,加载到本地,而音乐需要缓冲,边下边播.在iOS中只有小于30s的音乐才可以使用音效的方式进行播放.

  • 2.播放音效的实现思路:初始化soundID -> 获取音频文件的本地路径(NSURL类型) ->创建soundID -> 进行播放.

        音效播放的优化:以键值对的形式对音频文件和对应的soundID进行缓存,获取之前先判断对应的soundID是否已经在,存在的话直接在内存中取,不存在才创建:
        SystemSoundID systemSoundID;
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.caf" withExtension:nil];
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &systemSoundID);
        AudioServicesPlaySystemSound(systemSoundID);
        
        在接收到内存警告的情况下:释放soundID对应的内存地址,清空内存缓存.
        //释放soundID对应的内存地址
        for (NSNumber *soundIDNum in self.soundIDCache.allValues) {
              
              AudioServicesDisposeSystemSoundID([soundIDNum unsignedIntValue]);
        }
    
  • 3.框架:AVFoundation.

  • 4.关键类:SystemSoundID,每个音频文件使用音效方式处理时,会完整的添加到内存中,并被赋予一个声音ID.

  • 5.C的对象和OC对象的转化中内存管理:

      __bridge 用于Foundation中的类和CoreFoundation中的类相互转换,并且内存管理所有权不会改变。
      __bridge_retained 只能用于Foundation对象转CoreFoundation引用,而且内存管理的所有权会移交给引CoreFoundation的引用(注意手动内存管理)。
      __bridge_transfer 只能用于CoreFoundation引用转Foundation对象,而且内存管理的所有权会移交给引Foundation(会自动内存管理,不需要手动释放)。
    

音乐

1.框架:AVFoundation

2.关键类:AVAudioPlayer (只能播放本地音乐).

  对象方法创建:  _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

3.音乐的播放.暂停和停止的实现:根据音频文件路径初始化播放器 -> 进行缓冲

  [self.player prepareToPlay];

4.注意点:停止播放是音乐停止缓冲,但播放进度并不会清零.暂停音乐是暂时停止播放,但缓冲继续.音乐播放,隐式缓冲.

  关键方法: 
    -(void)play;//播放
    -(void)prepareToPlay;//缓存播放
    -(void)pause;//暂停
    -(void)stop;//停止

录音

  • 1.录音功能的实现:

      生成录音的存放路径(沙盒路径,拼接文件名:stringByAppendingPathComponent:@"音频名.caf") -> 设置采样率和位深 -> 对象方法创建录音机对象
    
  • 2.框架:AVFoundation.

    • 关键类:AVFoundationRecorder.

    • 关键方法:

          -(void)record;//录制
          -(void)pause;//暂停
          -(void)stop;//停止
      
  • 3.设置采样率和位深:

      NSDictionary *settings = @{AVSampleRateKey:@44100,AVLinearPCMBitDepthKey:@16};
    
  • 4.注意点:

      真机进行录音时,需要请求用户授权.在info.plist进行麦克风的授权说明.
    
  • 5.检测录音音量变化(&静默2s停止录音)

      //开启检测音量变化
      self.recorder.meteringEnabled = YES;
    
      //开启定时器
      [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    
      - (void)updateMeters{
          //更新音量变化
          [self.recorder updateMeters];
          //获取瞬时音量
          float power = [self.recorder peakPowerForChannel:0];
          NSLog(@"%f", power);
          //静默两秒后就停止录音
          if (power < -30) {
              //累计静默计数
              self.muteCount++;
              if (self.muteCount >= 120) { //静默两秒钟
                  //停止录音
                  [self.recorder stop];
                  //停止定时器
                  [self.displayLink invalidate];
              }
              
          } else {
              
              //有声音,就重新计数
              self.muteCount = 0;
          }
      }
    

视频

  • 1.播放视频的三个框架;
  • AVFoundation:提供了相对底层的API,不带界面效果.
  • MediaPlayer:对AVFoundation进行了封装,提供了较为简便的播放器使用.
  • AVKit:ios9推出,集AVFoundation和MediaPlayer之大成.
  • 2.播放器的创建

  • 1> MPMoviewPlayerViewController(带界面的视频播放器):

      获取视频文件的url路径 ->对象方法创建视频播放控制器 ->modal展示.
    
  • 2> MPMoviewPlayerController(不带界面的视频播放器):

      获取视频文件路径 ->创建控制器对象 ->将播放器的视图添加到要展示的界面上 ->[控制器对象 play];
    
  • 3> AVPlayer,偏底层,既可以播放音频又可以播放视频,播放视频需要添加layer到父视图上.

    //创建资源对象  获取文件信息
    AVAsset *asset = [AVAsset assetWithURL:[NSURL URLWithString:@"http://baobab.wdjcdn.com/14676170652191(23).mp4"]];
    //创建播放项目  曲目
    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
    //AVPlayer既可以播音频也可以播视频,可以本地也可以播网络
    self.avPlayer = [[AVPlayer alloc] initWithPlayerItem:item];
    //设置视图layer
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
    [self.view.layer addSublayer:layer];
    layer.frame = [UIScreen mainScreen].bounds;
    //播放
    [self.avPlayer play];
    
  • 4> AVPlayerViewController

    //带界面的播放器
    AVPlayerViewController *playerVc = [[AVPlayerViewController alloc] init];
    //设置播放器
    //创建资源对象  获取文件信息
    AVAsset *asset = [AVAsset assetWithURL:[NSURL URLWithString:@"http://baobab.wdjcdn.com/14676170652191(23).mp4"]];
    //创建播放项目  曲目
    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
    AVPlayer *avPlayer = [AVPlayer playerWithPlayerItem:item];
    playerVc.player = avPlayer;
    //进行modal展示
    [self presentViewController:playerVc animated:YES completion:nil];
    [avPlayer play];
    
  • 3.特殊功能:

    • 1> 横屏全屏播放(视图旋转90度,frame设置为屏幕大小)

      [UIView animateWithDuration:0.25 animations:^{
          self.playerController.view.transform = CGAffineTransformRotate(self.playerController.view.transform, M_PI_2);
          self.playerController.view.frame = [UIScreen mainScreen].bounds;
      }];
      
    • 2> 获取全屏的Down事件(viewDidLoad中用通知监听退出全屏事件) 退出全屏&暂停时,说明触发了Down事件

        //监听通知  退出全屏时
       [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didExitFullScreen) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
      
    • 3> 已经退出全屏后调用

        - (void)didExitFullScreen{
      
        //判断播放状态
        if (self.playerController.playbackState == MPMoviePlaybackStatePaused) {
              NSLog(@"点击Down");
              //移除视图
              [self.playerController.view removeFromSuperview];
              }
        }
      

视频截图(本质获取媒体文件中需求的关键帧图片)

  • 1.实现思路:

      根据文件路径,创建视频文件资源(AVAsset) -> 创建媒体文件图片生成器(AVAssetImageGenerator) -> 获取当前播放时间 -> 生成图片:[图片生成器对象 generateCGImageAsynchronouslyForTimes:...];
    
  • 2.关键类:

      AVAsset(资源)
      媒体文件图片生成器(AVAssetImageGenerator)
    
  • 3.关键方法:

      创建媒体资源:AVAsset的类方法创建
      
      创建媒体文件图片生成器对象: AVAssetImageGenerator(类方法创建).
      
      获取当前媒体文件的播放时间:CMTime time  = self.avplayer.currentTime.
      
      生成图片:[媒体文件图片生成器对象 generateCGImagesAsynchronouslyForTimes...];
      
      //死锁: 在某个线程中嵌套该线程的同步任务才会死锁
    

视频录制

  • 1.框架:AVFoundation.

  • 2.关键类:

      AVCaptureDeviceInput(摄入设备)
      AVCaptureMoviewFileOutput(输出设备)
      AVCaptureSession(采集会话)
      AVCaptureVideoPreviewLayer(预览视图)
    
  • 3.视频录制的实现思路:

          输入设备(音频输入麦克风,视频输入摄像头) -> 输出设备(视频文件) ->管理输入设备和输出设备的会话 ->预览视图 ->开始录制 ->录制视频的保存路径,输出设备开始录制 ->停止录制.
    
    • 输入音频设备:

        AVCaptureDevice *video = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
      
    • 输入视频设备:

        self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:video error:nil];
      
    • 输出设备:

        self.output = [[AVCaptureMovieFileOutput alloc] init];
      
    • 会话:

        self.session = [[AVCaptureSession alloc] init];
        //加入输入设备
        if ([self.session canAddInput:self.videoInput]) {
            
            [self.session addInput:self.videoInput];
        }
        if ([self.session canAddInput:self.audioInput]) {
            
            [self.session addInput:self.audioInput];
        }
        //加入输出设备
        if ([self.session canAddOutput:self.output]) {
            [self.session addOutput:self.output];
        }
      
    • 预览视图:

        self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
      
    • 开始采集:

        [self.session startRunning];
      
    • 开始录制:

        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"录制.mp4"];
        NSURL *url = [NSURL fileURLWithPath:path];
        [self.output startRecordingToOutputFileURL:url recordingDelegate:self];
      
    • 停止录制(三步:停止录制 停止采集和移除预览视图)

        [self.output stopRecording];
        [self.session stopRunning];
        [self.previewLayer removeFromSuperlayer];
      
  • 4.在访问麦克风和摄像头时应请求用户授权,在info,plist文件中对麦克风和摄像头进行描述.

视频转制(输出相册中的视频并压缩)

  • 1.实现思路:

      创建UIImagePickerController对象 ->设置代理,设置资源类型(获取图片)和媒体类型(获取视频) ->modal展示 ->在代理方法中获取路径获取媒体文件 ->创建媒体转制会话 ->设置输出的路径 ->设置可支持的输出格式 ->输出视频 ->销毁UIImagePickerController对象
    
  • 2.步骤:

    • 创建控制器:

        UIImagePickerController *imgVc = [[UIImagePickerController alloc] init];
      
    • 设置代理:

        imgVc.delegate = self;
      
    • 设置类型:

        imgVc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
      
    • 获取相册中视频 需要设置媒体类型:

        imgVc.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
      
    • modal展示:

        [self presentViewController:imgVc animated:YES completion:nil];
      
    • 转制视频:

      - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
      
            NSLog(@"%@", info);
            //获取媒体文件
            NSURL *url = info[UIImagePickerControllerMediaURL];
            AVAsset *asset = [AVAsset assetWithURL:url];
            //创建媒体转制会话
            AVAssetExportSession *session = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetLowQuality];
            //设置转出的路径
            NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"转出的视频.mp4"];
            session.outputURL = [NSURL fileURLWithPath:filePath];
            //获取支持的转出格式
            [session determineCompatibleFileTypesWithCompletionHandler:^(NSArray<NSString *> * _Nonnull compatibleFileTypes) {
        
            NSLog(@"%@", compatibleFileTypes);
            }];
            //设置转出的格式 转出格式必须支持
            session.outputFileType = @"public.mpeg-4";
            //转出视频
            [session exportAsynchronouslyWithCompletionHandler:^{
      
            NSLog(@"完成转出");
            //销毁控制器
            [picker dismissViewControllerAnimated:YES completion:nil];
            }];
        }
      

谢谢观赏,喜欢的话就点一下!

相关文章

网友评论

      本文标题:音视频

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