視頻直播
<h5>拉流:</h5>
從服務(wù)器獲取視頻直播流地址给梅,播放直播 使用IJKMediaFramework.framework
使用:
IJKFFOptions *options = [IJKFFOptions optionsByDefault];
[options setPlayerOptionIntValue:1 forKey:@"videotoolbox"];
// 幀速率(fps) (可以改,確認非標準楨率會導致音畫不同步钾虐,所以只能設(shè)定為15或者29.97)
[options setPlayerOptionIntValue:29.97 forKey:@"r"];
// -vol——設(shè)置音量大小,256為標準音量。(要設(shè)置成兩倍音量時則輸入512啰脚,依此類推
[options setPlayerOptionIntValue:512 forKey:@"vol"];
IJKFFMoviePlayerController *moviePlayer = [[IJKFFMoviePlayerController alloc] initWithContentURLString:flv withOptions:options];
moviePlayer.view.frame = self.contentView.bounds;
// 填充fill
moviePlayer.scalingMode = IJKMPMovieScalingModeAspectFill;
// 設(shè)置自動播放(必須設(shè)置為NO, 防止自動播放, 才能更好的控制直播的狀態(tài))
moviePlayer.shouldAutoplay = NO;
// 默認不顯示
moviePlayer.shouldShowHudView = NO;
[self.contentView insertSubview:moviePlayer.view atIndex:0];
[moviePlayer prepareToPlay];
self.moviePlayer = moviePlayer;
<h5>推流:</h5>
開始直播,視頻采集和視頻流處理與傳輸
直播采用L
LFLiveKit 支持的流類型
rtmp格式 实夹、 tcp 傳輸flv格式
<h5>使用</h5>
開播邏輯
- (void)startLive {
MPLiveModel *liveModel = [ZQGlobalObject sharedZQGlobalObject].liveModel;
// 拼接推流地址 “url/流名”
NSString *url = [NSString stringWithFormat:@"%@/%@", liveModel.rtmpUrl, liveModel.videoId];
// 創(chuàng)建流對象
LFLiveStreamInfo *stream = [LFLiveStreamInfo new];
stream.url = url;
// 推流對象開始推流
[_session startLive:stream];
}
進出后臺處理
#pragma mark 應(yīng)用程序通知監(jiān)聽
- (void)applicationNotification:(NSNotification *)note {
if (_session) {
// 進入后臺
if (note.name == UIApplicationDidEnterBackgroundNotification) { // 進入后臺
NSLog(@"進入后臺");
[_controlView pauseLive];
// 從后臺回到直播間
} else if (note.name == UIApplicationWillEnterForegroundNotification) {
if (!_session.running) {
_session.running = YES;
}
[self startLive];
}
}
}
退出直播間橄浓,釋放對象
- (void)dealloc {
if (_session) {
_session.delegate = nil;
_session = nil;
}
NSLog(@"退出直播間");
}
創(chuàng)建推流對象并設(shè)置播放參數(shù)
- (LFLiveSession *)session {
if(!_session){
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfigurationForQuality:LFLiveVideoQuality_Medium2 orientation:UIInterfaceOrientationPortrait] liveType:LFLiveRTMP];
_session.delegate = self;
_session.running = YES;
_session.preView = _preview;
}
return _session;
}
創(chuàng)建推流要展示推流效果的視圖對象
- (MPLiveControlView *)controlView {
if (_controlView == nil) {
_controlView = [[MPLiveControlView alloc] initWithFrame:self.view.frame];
_controlView.delegate = self;
_controlView.session = self.session;
}
return _controlView;
}
推流狀態(tài)的回調(diào)
- (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange:(LFLiveState)state{
NSLog(@"liveStateDidChange: %ld", state);
WS(weakSelf);
dispatch_async(dispatch_get_main_queue(), ^{
switch (state) {
case LFLiveReady:
[weakSelf.controlView setLiveState:MPLiveStateLoading];
break;
case LFLivePending:
[weakSelf.controlView setLiveState:MPLiveStateLoading];
break;
case LFLiveStart:
[weakSelf.controlView setLiveState:MPLiveStatePlay];
break;
case LFLiveError:
// _stateLabel.text = @"連接錯誤";
break;
case LFLiveStop:
[weakSelf.controlView setLiveState:MPLiveStateStop];
break;
default:
break;
}
});
}
- (void)liveSession:(nullable LFLiveSession *)session debugInfo:(nullable LFLiveDebug*)debugInfo{
NSLog(@"debugInfo: %lf", debugInfo.dataFlow);
}
- (void)liveSession:(nullable LFLiveSession*)session errorCode:(LFLiveSocketErrorCode)errorCode{
NSLog(@"errorCode: %ld", errorCode);
}
彈幕可以使用BarrageRenderer
簡單使用:
_renderer = [[BarrageRenderer alloc] init];
// 設(shè)置彈幕的顯示區(qū)域. 基于父控件的.
_renderer.canvasMargin = UIEdgeInsetsMake(ALinScreenHeight * 0.3, 10, 10, 10);
[self.contentView addSubview:_renderer.view];
彈幕配置
#pragma mark - 彈幕描述符生產(chǎn)方法
/// 生成精靈描述 - 過場文字彈幕
- (BarrageDescriptor *)walkTextSpriteDescriptorWithDirection:(NSInteger)direction
{
BarrageDescriptor * descriptor = [[BarrageDescriptor alloc]init];
descriptor.spriteName = NSStringFromClass([BarrageWalkTextSprite class]);
descriptor.params[@"text"] = self.danMuText[arc4random_uniform((uint32_t)self.danMuText.count)];
descriptor.params[@"textColor"] = Color(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256));
descriptor.params[@"speed"] = @(100 * (double)random()/RAND_MAX+50);
descriptor.params[@"direction"] = @(direction);
descriptor.params[@"clickAction"] = ^{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"彈幕被點擊" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[alertView show];
};
return descriptor;
}
[_renderer start];