[iOS开发]AVFoundation浅学习

Posted Billy Miracle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[iOS开发]AVFoundation浅学习相关的知识,希望对你有一定的参考价值。

写在前面:

众所周知,手机可以播放视频,音乐,甚至和你“交谈”,那怎么实现这些呢?

正文

合成语音:

- (void)speakHintMessage 
  
    // 这样子可以简单的播放一段语音
    AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
    // Utterance 表达方式
    AVSpeechSynthesisVoice * voice  = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-HK"];
    AVSpeechUtterance  *utterance = [[AVSpeechUtterance alloc] initWithString:@"你是猪,你是猪,你是猪,你是猪,你是猪,你是猪"];
    utterance.rate  = 0.5; // 这个是播放速率 默认1.0
    utterance.voice = voice;
    utterance.pitchMultiplier = 1.0;        // 可在播放待定语句时候改变声调
    utterance.postUtteranceDelay = 0.5; // 语音合成器在播放下一条语句的时候有短暂的停顿  这个属性指定停顿的时间
    [synthesizer speakUtterance:utterance];
        
    /*
        "[AVSpeechSynthesisVoice 0x978a0b0] Language: th-TH",
        "[AVSpeechSynthesisVoice 0x977a450] Language: pt-BR",
        "[AVSpeechSynthesisVoice 0x977a480] Language: sk-SK",
        "[AVSpeechSynthesisVoice 0x978ad50] Language: fr-CA",
        "[AVSpeechSynthesisVoice 0x978ada0] Language: ro-RO",
        "[AVSpeechSynthesisVoice 0x97823f0] Language: no-NO",
        "[AVSpeechSynthesisVoice 0x978e7b0] Language: fi-FI",
        "[AVSpeechSynthesisVoice 0x978af50] Language: pl-PL",
        "[AVSpeechSynthesisVoice 0x978afa0] Language: de-DE",
        "[AVSpeechSynthesisVoice 0x978e390] Language: nl-NL",
        "[AVSpeechSynthesisVoice 0x978b030] Language: id-ID",
        "[AVSpeechSynthesisVoice 0x978b080] Language: tr-TR",
        "[AVSpeechSynthesisVoice 0x978b0d0] Language: it-IT",
        "[AVSpeechSynthesisVoice 0x978b120] Language: pt-PT",
        "[AVSpeechSynthesisVoice 0x978b170] Language: fr-FR",
        "[AVSpeechSynthesisVoice 0x978b1c0] Language: ru-RU",
        "[AVSpeechSynthesisVoice 0x978b210] Language: es-MX",
        "[AVSpeechSynthesisVoice 0x978b2d0] Language: zh-HK",
        "[AVSpeechSynthesisVoice 0x978b320] Language: sv-SE",
        "[AVSpeechSynthesisVoice 0x978b010] Language: hu-HU",
        "[AVSpeechSynthesisVoice 0x978b440] Language: zh-TW",
        "[AVSpeechSynthesisVoice 0x978b490] Language: es-ES",
        "[AVSpeechSynthesisVoice 0x978b4e0] Language: zh-CN",
        "[AVSpeechSynthesisVoice 0x978b530] Language: nl-BE",
        "[AVSpeechSynthesisVoice 0x978b580] Language: en-GB",
        "[AVSpeechSynthesisVoice 0x978b5d0] Language: ar-SA",
        "[AVSpeechSynthesisVoice 0x978b620] Language: ko-KR",
        "[AVSpeechSynthesisVoice 0x978b670] Language: cs-CZ",
        "[AVSpeechSynthesisVoice 0x978b6c0] Language: en-ZA",
        "[AVSpeechSynthesisVoice 0x978aed0] Language: en-AU",
        "[AVSpeechSynthesisVoice 0x978af20] Language: da-DK",
        "[AVSpeechSynthesisVoice 0x978b810] Language: en-US",
        "[AVSpeechSynthesisVoice 0x978b860] Language: en-IE",
        "[AVSpeechSynthesisVoice 0x978b8b0] Language: hi-IN",
        "[AVSpeechSynthesisVoice 0x978b900] Language: el-GR",
        "[AVSpeechSynthesisVoice 0x978b950] Language: ja-JP" )
        */
    // 通过这个方法可以看到整个支持的会话的列表,信息如上输出
    NSLog(@"目前支持的语音列表:%@",[AVSpeechSynthesisVoice speechVoices]);

调用上面的方法,就可以让你的手机“说话”了。

播放本地音频:

我们可能会经常使用一些音乐软件来听音乐,比如,扣扣音乐,🍎Music等等等等。那么,我们如何自己来制作一个“酷炫”的音乐播放器呢?

- (void)creatAVAudioPlayer 
    NSError* err;
    //选择本地路径
    NSString *path = @"/Users/zhangbotian/Music/网易云音乐/Taylor Swift - Welcome To New York.mp3";
    BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path];
    if (isExist) 
        NSLog(@"111");
    
//    NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:path]];
    NSDictionary *dictionary = [self dataInfoFromFileURL:[NSURL fileURLWithPath:path]];
    //获取数据
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(screenWidth * 0.15, 100, screenWidth * 0.7, screenWidth * 0.7)];
    imageView.image = [dictionary valueForKey:@"Artwork"];
    [self.view addSubview:imageView];
    
    _buttonPlay = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    _buttonPlay.frame = CGRectMake((screenWidth - 90) / 2, 250 + screenWidth * 0.7, 90, 90);
    
//    [_buttonPlay setTitle:@"播放" forState:UIControlStateNormal];
    [_buttonPlay setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
    _buttonPlay.tag = 0;
    [self.view addSubview:_buttonPlay];
    [_buttonPlay addTarget:self action:@selector(playRadio:) forControlEvents:UIControlEventTouchUpInside];
    
    _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(50, 150 + screenWidth * 0.7, screenWidth - 100, 50)];
    _progressView.progress = 0;
//    [self.view addSubview: _progressView];
    _slider = [[UISlider alloc] initWithFrame:CGRectMake(50, 200 + screenWidth * 0.7, screenWidth - 100, 50)];
    _slider.minimumValue = 0;
    _slider.maximumValue = 1;
    _slider.tintColor = [UIColor systemGreenColor];
    [self.view addSubview:_slider];
    [_slider addTarget:self action:@selector(slide) forControlEvents:UIControlEventValueChanged];
    
    _player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] fileTypeHint:@"mp3" error: &err];//使用本地URL创建AVAudioPlayer
    if (err) 
        NSLog(@"%@", err);
    
    _player.volume = 0.2;//0.0~1.0之间
    _player.numberOfLoops = 3;
    _player.delegate = self;
    [_player prepareToPlay];//分配播放所需的资源,并将其加入内部播放队列
//    [_player play];//播放
//    [player stop];//停止
    
    _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(screenWidth * 0.15, 100 + screenWidth * 0.7, screenWidth * 0.7, 70)];
    _titleLabel.textAlignment = NSTextAlignmentLeft;
    _titleLabel.font = [UIFont systemFontOfSize:26];
    _titleLabel.text = [dictionary valueForKey:@"Title"];
    [self.view addSubview:_titleLabel];
    
    _nameButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    _nameButton.frame = CGRectMake(screenWidth * 0.15, 170 + screenWidth * 0.7, 100, 30);
    [_nameButton setTitle:[dictionary valueForKey:@"Artist"] forState:UIControlStateNormal];
    [_nameButton setTintColor:[UIColor grayColor]];
    [self.view addSubview:_nameButton];
    
    _volumeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    _volumeButton.frame = CGRectMake((screenWidth - 200) / 2 + 160, 250 + screenWidth * 0.7 + 25, 32, 32);
    [self.view addSubview:_volumeButton];
    [_volumeButton setBackgroundImage:[UIImage imageNamed:@"yinliang.png"] forState:UIControlStateNormal];
    [_volumeButton addTarget:self action:@selector(pressVolume:) forControlEvents:UIControlEventTouchUpInside];
    
    _volumeSlider = [[UISlider alloc] init];
    _volumeSlider.transform = CGAffineTransformMakeRotation(-M_PI_2);
    _volumeSlider.frame = CGRectMake(0, 0, 32, 100);
    _volumeSlider.minimumValue = 0;
    _volumeSlider.maximumValue = 1;
    _volumeSlider.value = _player.volume;
//    [self.view addSubview:_volumeSlider];
    
    _volumeBackGroundView = [[UIView alloc] initWithFrame:CGRectMake((screenWidth - 200) / 2 + 160, 250 + screenWidth * 0.7 + 25 - 100, 32, 100)];
    _volumeBackGroundView.backgroundColor = [UIColor lightGrayColor];
    _volumeBackGroundView.alpha = 0.9;
    [self.view addSubview:_volumeBackGroundView];
    [_volumeBackGroundView addSubview:_volumeSlider];
    _volumeBackGroundView.hidden = YES;
    [_volumeSlider addTarget:self action:@selector(slideVolume) forControlEvents:UIControlEventValueChanged];
    

获取数据方法:

//获取数据方法
- (NSDictionary *)dataInfoFromFileURL:(NSURL *)fileURL 
    // 创建字典
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    // 创建信号量(将异步变成同步)
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    AVAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
    [asset loadValuesAsynchronouslyForKeys:@[@"commonMetadata"] completionHandler:^
        // 发送信号量
        dispatch_semaphore_signal(semaphore);
    ];
    // 无限等待
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    // 获取数据
    NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtwork keySpace:AVMetadataKeySpaceCommon];
    for (AVMetadataItem *item in artworks) 
        if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) 
            // 获取图片
            UIImage  *image = [UIImage imageWithData:item.dataValue];
            [dic setObject:image forKey:@"Artwork"];
        
        if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) 
            UIImage *image = [UIImage imageWithData:item.dataValue];
            [dic setObject:image forKey:@"Artwork"];
        
    
    //获取歌手
    artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyArtist keySpace:AVMetadataKeySpaceCommon];
    for (AVMetadataItem *item in artworks) 
        if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) 
            NSString *name = [NSString stringWithFormat:@"%@", item.value];
            [dic setObject:name forKey:@"Artist"];
        
    
    //获取歌曲名
    artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata withKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon];
    for (AVMetadataItem *item in artworks) 
        if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) 
            NSString *title = [NSString stringWithFormat:@"%@", item.value];
            [dic setObject:title forKey:@"Title"];
        
    
    return [NSDictionary dictionaryWithDictionary: dic];

接下来,再实现一些按钮和进度条的方法就可以实现了。我们看一下效果图:

未完待续。。。

以上是关于[iOS开发]AVFoundation浅学习的主要内容,如果未能解决你的问题,请参考以下文章

IOS开发中AVFoundation中AVAudioPlayer的使用

iOS陆哥开发笔记 (AVFoundation简单介绍)

iOS开发进阶 - 用AVFoundation自定义视频录制功能

iOS开发--二维码的扫描

iOS - 使用 AVFoundation 录制声音后 iPhone 声音级别低

IOS开发之学习《AV Foundation 开发秘籍》