iOS 音视频

音效

  • 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.视频录制的实现思路:

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

    1>输入音频设备:

      AVCaptureDevice *video = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    

    2>输入视频设备:

      self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:video error:nil];
    

    3>输出设备:

      self.output = [[AVCaptureMovieFileOutput alloc] init];
    

    4>会话:

      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];
      }
    

    5>预览视图:

      self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    

    6>开始采集:

      [self.session startRunning];
    

    7>开始录制:

      NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"录制.mp4"];
      NSURL *url = [NSURL fileURLWithPath:path];
      [self.output startRecordingToOutputFileURL:url recordingDelegate:self];
    

    8>停止录制(三步:停止录制 停止采集和移除预览视图)

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

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

  • 1.实现思路:

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

    1>创建控制器:

      UIImagePickerController *imgVc = [[UIImagePickerController alloc] init];
    

    2>设置代理:

      imgVc.delegate = self;
    

    3>设置类型:

      imgVc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    

    4>获取相册中视频 需要设置媒体类型:

      imgVc.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
    

    5>modal展示:

      [self presentViewController:imgVc animated:YES completion:nil];
    

    7>转制视频:

      - (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];
    	}];
      }
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值