苹果设备直播教程,苹果直播最佳设置

首页 > 数码 > 作者:YD1662023-04-21 13:55:42

iOS 直播流程概述

苹果设备直播教程,苹果直播最佳设置(1)

写在前面

本文目的在于带大家了解一场直播背后,需要经历哪些阶段,以及每个阶段都做了哪些工作,才能够把主播的声音画面送到观众的面前。我们把直播的流程划分为以下六个阶段:

  1. 采集
  2. 处理
  3. 编码
  4. 封装
  5. 网络传输
  6. 播放

下面来一一介绍。

采集

采集又分为视频采集、音频采集。

一般来说,我们会借助系统 api 来实现这一部分的工作。以 iOS 为例,需要用到 AVFoundation 框架来获取手机摄像头拍到的视频数据,或者使用 ReplayKit 录制屏幕,以及麦克风收集到的音频数据。

视频采集:摄像头核心类 AVCaptureXXX

使用摄像头采集视频的几个核心类如下图所示:

苹果设备直播教程,苹果直播最佳设置(2)

具体代码如下:

// 1. 创建一个 session var session = AVCaptureSession.init() // 2. 获取硬件设备:摄像头 guard let device = AVCaptureDevice.default(for: .video) else { print("获取后置摄像头失败") return } // 3. 创建 input let input = try AVCaptureDeviceInput.init(device: device) if session.canAddInput(input) { session.addInput(input) } // 4. 创建 output let videoOutput = AVCaptureVideoDataOutput.init() let pixelBufferFormat = kCVPixelBufferPixelFormatTypeKey as String // 设置 yuv 视频格式 videoOutput.videoSettings = [pixelBufferFormat: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] videoOutput.setSampleBufferDelegate(self, queue: outputQueue) if session.canAddOutput(videoOutput) { session.addOutput(videoOutput) } // 5. 设置预览 layer:AVCaptureVideoPreviewLayer let previewViewLayer = videoConfig.previewView.layer previewViewLayer.backgroundColor = UIColor.black.cgColor let layerFrame = previewViewLayer.bounds let videoPreviewLayer = AVCaptureVideoPreviewLayer.init(session: session) videoPreviewLayer.frame = layerFrame videoConfig.previewView.layer.insertSublayer(videoPreviewLayer, at: 0) // 6. 在 output 回调里处理视频帧:AVCaptureVideoDataOutputSampleBufferDelegate func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { // todo: sampleBuffer 视频帧 } 色彩二次抽样:YUV

一般来说,我们看到的媒体内容,都经过了一定程度的压缩。包括直接从 iPhone 摄像头采集的图像数据,也会经过色彩二次抽样这一压缩过程。

在上一步中创建 output 的时候,我们设置了视频的输出格式是kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 的。在这句代码中,我们需要注意到两个地方:420和YpCbCr。

人眼对亮点信息更敏感,单靠 Y 数据,可以完美呈现黑白图像;也就是说可以压缩 UV 信息,而人眼难以发现。

下右图:单靠黑白亮度信息,已经足以描述整个照片的纹理。加上 uv 色彩信息后,就成了下左图的彩色图片的效果。

4:2:0 中,第一个数,代表几个关联的色块(一般是4);第二个数,代表第一行中包含色彩 uv 信息的像素个数;第三个数,代表第二行中包含色彩 uv 信息的像素个数。(每个像素里都包含亮度信息 Y)

取样的时候,一些专业的相机会以 4:4:4 的参数捕捉图像,面向消费者的 iPhone 相机,通常用 4:2:0 的参数,也能拍出来高质量的视频或图片。!

视频采集:录屏

录屏又分为两种:

1. 应用内采集

// iOS 录屏使用的框架是 ReplayKit import ReplayKit // 开始录屏 RPScreenRecorder.shared().startCapture { sampleBuffer, bufferType, err in } completionHandler: { err in } // 结束录屏 RPScreenRecorder.shared().stopCapture { err in }

针对应用内录屏,有以下两个 Tip:

2. 应用外采集

应用外采集需要创建一个 broadcast upload extension,创建完成后会生成一个 SampleHander 类,在这个类里面可以获取到采集的视频数据。

苹果设备直播教程,苹果直播最佳设置(3)

class SampleHandler: RPBroadcastSampleHandler { func sohuSportUserDefaults() -> UserDefaults? { return UserDefaults.init(suiteName: "com.xxx.xx") } override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) { // 开始录屏,setupInfo 是从 UI extension 传递过来的参数 } override func broadcastPaused() { // 暂停录屏 } override func broadcastResumed() { // 继续录屏 } override func broadcastFinished() { // 录屏结束 } // 录屏回调 override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { // sampleBuffer switch sampleBufferType { case .video: // 视频 case .audioApp: // 应用内声音 case .audioMic: // 麦克风声音 } } }

extension 进程和主 app 进程间通信,可以通过以下几种方式:

音频采集:Audio Unit

iOS 直播中的音频采集,我们一般会用到 Audio Unit 这一底层框架,这一框架允许我们在采集的时候对录制的音频进行一些参数设置,以便获取到最高质量与最低延迟的音频。核心代码如下:

// 创建 audio unit self.component = AudioComponentFindNext(NULL, &acd); OSStatus status = AudioComponentInstanceNew(self.component, &_audio_unit); if (status != noErr) { [self handleAudiounitCreateFail]; } // asbd AudioStreamBasicDescription desc = {0}; desc.mSampleRate = 44100; // 采样率 desc.mFormatID = kAudioFormatLinearPCM; // 格式 desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; desc.mChannelsPerFrame = 1; // 声道数量 desc.mFramesPerPacket = 1; // 每个包中有多少帧, 对于PCM数据而言,因为其未压缩,所以每个包中仅有1帧数据 desc.mBitsPerChannel = 16; desc.mBytesPerFrame = desc.mBitsPerChannel / 8 * desc.mChannelsPerFrame; desc.mBytesPerPacket = desc.mBytesPerFrame * desc.mFramesPerPacket; // 回调函数 AURendercallbackStruct callback; callback.inputProcRefCon = (__bridge void *)(self); callback.inputProc = handleVideoInputBuffer; // 设置属性 AudioUnitSetProperty(self.audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &desc, sizeof((desc))); AudioUnitSetProperty(self.audio_unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &callback, sizeof((callback))); UInt32 flagOne = 1; AudioUnitSetProperty(self.audio_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flagOne, sizeof(flagOne)); // 配置 AVAudioSession AVAudioSession *session = [AVAudioSession sharedInstance]; [session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:nil]; [session setActive:YES withOptions:kAudioSessionSetActiveFlag_NotifyOthersOnDeactivation error:nil]; [session setActive:YES error:nil]; #pragma mark - 音频回调函数 static OSStatus handleVideoInputBuffer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { // } 处理

对视频来说,这一阶段的主要工作是拿到 SampleBuffer,做一下美白、磨皮、滤镜等效果。本质上来说,这些操作都是在修改每一帧像素点的坐标和颜色变化,流程如下:

苹果设备直播教程,苹果直播最佳设置(4)

首页 123下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.