最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS開發(fā)項(xiàng)目- 基于WebSocket的聊天通訊(2)

 更新時(shí)間:2016年11月11日 08:51:04   作者:小兵快跑  
這篇文章主要介紹了iOS開發(fā)項(xiàng)目- 基于WebSocket的聊天通訊,可以實(shí)現(xiàn)錄音和音樂播放,有需要的可以了解一下。

公司項(xiàng)目需要開發(fā)一個(gè)類似QQ、微信的即時(shí)IM聊天功能,做到實(shí)時(shí)監(jiān)控消息,需要用的技術(shù)是websocket,今天整理下語言聊天這塊;其實(shí)語言聊天,包含兩部分,錄音和音樂播放,關(guān)于簡(jiǎn)單語言聊天功能如下圖:

錄音

在AVFoundation框架中有一個(gè)AVAudioRecorder類專門處理錄音操作,它同樣支持多種音頻格式。與AVAudioPlayer類似,你完全可以將它看成是一個(gè)錄音機(jī)控制類,下面是常用的屬性和方法:

先來了解下AVAudioRecorder的常用屬性:

@property (readonly, getter=isRecording) BOOL recording;//是否正在錄音
@property (readonly) NSDictionary<NSString *, id> *settings;//錄音配置
@property (readonly) NSURL *url;//錄音文件存放URL
@property (readonly) NSTimeInterval currentTime;//錄音時(shí)長(zhǎng)
@property (getter=isMeteringEnabled) BOOL meteringEnabled;//是否監(jiān)控聲波

常用對(duì)象方法:

- (BOOL)prepareToRecord;//為錄音準(zhǔn)備緩沖區(qū)
- (BOOL)record;//錄音開始,暫停后調(diào)用會(huì)恢復(fù)錄音
- (BOOL)recordAtTime:(NSTimeInterval)time;//在指定時(shí)間后開始錄音
- (BOOL)recordForDuration:(NSTimeInterval) duration;//按指定時(shí)長(zhǎng)錄音
- (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval)duration;//上面2個(gè)的合體
- (void)pause; //中斷錄音
- (void)stop; //停止錄音
- (BOOL)deleteRecording;//刪除錄音,必須先停止錄音再刪除

常用的代理方法:

//錄音完成后調(diào)用
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag;//錄音編碼發(fā)送錯(cuò)誤時(shí)調(diào)用
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error;

音頻

如果播放較大的音頻或者要對(duì)音頻有精確的控制則System Sound Service可能就很難滿足實(shí)際需求了,通常這種情況會(huì)選擇使用AVFoundation.framework中的AVAudioPlayer來實(shí)現(xiàn)。AVAudioPlayer可以看成一個(gè)播放器,它支持多種音頻格式,而且能夠進(jìn)行進(jìn)度、音量、播放速度等控制

AVAudioPlayer的使用比較簡(jiǎn)單:

1.初始化AVAudioPlayer對(duì)象,此時(shí)通常指定本地文件路徑。

2.設(shè)置播放器屬性,例如重復(fù)次數(shù)、音量大小等。

3.調(diào)用play方法播放。

具體實(shí)現(xiàn)代碼

#import <AVFoundation/AVFoundation.h>
#define kRecordAudioFile @"myRecord.caf"


@interface ViewController ()<AVAudioRecorderDelegate>
{
  NSString *dateName;

}
@property (weak, nonatomic) IBOutlet UITableView *table;

@property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音頻錄音機(jī)
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;//音頻播放器,用于播放錄音文件


@property(nonatomic,strong) NSMutableArray *spaceData;


@end

@implementation ViewController
#pragma mark - 私有方法
/**
 * 設(shè)置音頻會(huì)話
 */
-(void)setAudioSession{

  AVAudioSession *audioSession=[AVAudioSession sharedInstance];
  //設(shè)置為播放和錄音狀態(tài),以便可以在錄制完之后播放錄音
  [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  [audioSession setActive:YES error:nil];
}



/**
 * 取得錄音文件設(shè)置
 *
 * @return 錄音設(shè)置
 */
-(NSDictionary *)getAudioSetting{
  NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
  //設(shè)置錄音格式
  [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
  //設(shè)置錄音采樣率,8000是電話采樣率,對(duì)于一般錄音已經(jīng)夠了
  [dicM setObject:@(8000) forKey:AVSampleRateKey];
  //設(shè)置通道,這里采用單聲道
  [dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
  //每個(gè)采樣點(diǎn)位數(shù),分為8、16、24、32
  [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
  //是否使用浮點(diǎn)數(shù)采樣
  [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
  //....其他設(shè)置等
  return dicM;
}
/**
 * 取得錄音文件保存路徑
 *
 * @return 錄音文件路徑
 */
-(NSURL *)getPlayPath:(NSString *)title{


  //  static int index = 0;

  NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  urlStr=[urlStr stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@",title,kRecordAudioFile]];
  NSLog(@"play file path:%@",urlStr);
  NSURL *url=[NSURL fileURLWithPath:urlStr];

  return url;
}

/**
 * 以日期為title,來保存錄音
 *
 * @return <#return value description#>
 */
- (NSString *) convertDateFromString
{
  NSDate *date = [NSDate date];
  //  NSLog(@"%@--askl",date);
  //  
  NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
  //zzz表示時(shí)區(qū),zzz可以刪除,這樣返回的日期字符將不包含時(shí)區(qū)信息。

  [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  NSString *destDateString = [dateFormatter stringFromDate:date];

  return destDateString;

}

長(zhǎng)按錄音,松開停止

- (void)setClikeSpaceState:(NSString *)aState
{
  NSLog(@"點(diǎn)擊語音---");  

  if([aState isEqualToString:@"begin"])
  {
    NSLog(@"begin---");

    dateName = [self convertDateFromString];
    //創(chuàng)建錄音文件保存路徑
    NSURL *url=[self getPlayPath:dateName];
    //創(chuàng)建錄音格式設(shè)置
    NSDictionary *setting=[self getAudioSetting];
    //創(chuàng)建錄音機(jī)
    NSError *error=nil;
    _audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];
    _audioRecorder.delegate=self;
    _audioRecorder.meteringEnabled=YES;//如果要監(jiān)控聲波則必須設(shè)置為YES

    if (![self.audioRecorder isRecording]) {
      [self.audioRecorder record];//首次使用應(yīng)用時(shí)如果調(diào)用record方法會(huì)詢問用戶是否允許使用麥克風(fēng)
      //    self.timer.fireDate=[NSDate distantPast];

      NSLog(@"111");
    }


  }else
  {
    NSLog(@"end---");


    /** 停止錄音*/
    [self.audioRecorder stop];


    /** 錄音地址*/
    NSURL *url = [self getPlayPath:dateName];

    /** 加載數(shù)據(jù)*/

    AVAudioPlayer  *audioPlayer1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

    Model *model = [[Model alloc]init];
    model.duration = [NSString stringWithFormat:@"%.f",audioPlayer1.duration];
    model.spacePath = dateName;



    /** table 刷新*/
    [self.spaceData addObject:model];
    [self.table reloadData];


    /** table 滾動(dòng)到當(dāng)前row*/

    [self.table selectRowAtIndexPath:[NSIndexPath indexPathForRow:(self.spaceData.count - 1) inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];






  }
}

點(diǎn)擊table 播放

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{


  Model *model = self.spaceData[indexPath.row];  

  /** 播放錄音*/
  NSURL *url=[self getPlayPath:model.spacePath];
  NSError *error=nil;
  _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
  _audioPlayer.numberOfLoops=0;

  [_audioPlayer prepareToPlay];
  [self.audioPlayer play];

  NSLog(@"%.0f---aaaa",_audioPlayer.duration);

  /** UIImage動(dòng)畫數(shù)組*/
  NSMutableArray  *imgData = [NSMutableArray array];
  for(int i=0;i<4;i++)
  {
    UIImage *aImage = [UIImage imageNamed:[NSString stringWithFormat:@"chat_receiver_audio_playing00%d",i]];
    [imgData addObject:aImage];

  }

  TwoTableViewCell *twoCell = [self.table cellForRowAtIndexPath:indexPath];




  /** 點(diǎn)擊動(dòng)畫*/

  [twoCell.speak setAnimationImages:imgData];
  //    [twoCell.speak setAnimationRepeatCount:1];
  [twoCell.speak setAnimationDuration:1];
  [twoCell.speak startAnimating];

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)([model.duration intValue] * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    [twoCell.speak stopAnimating];

  });

}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

贡嘎县| 安义县| 社旗县| 河津市| 广元市| 夏邑县| 日喀则市| 崇义县| 安图县| 城市| 乌什县| 盐津县| 武清区| 萨迦县| 韶山市| 广东省| 麻栗坡县| 宜城市| 鄂温| 康平县| 涞水县| 手机| 彩票| 神农架林区| 库尔勒市| 武陟县| 闵行区| 杨浦区| 永寿县| 托里县| 电白县| 浦江县| 修水县| 磐石市| 循化| 资阳市| 福建省| 吉隆县| 旌德县| 凤凰县| 远安县|