跳到主要内容

JPEG 图像直播

启动设备的 JPEG 直播模式,并渲染 SDK 提供的每个完整 JPEG 图像。兼容的 level-2 流还可提供 Opus 音频及可选的解码 PCM 数据。

前提条件​

  • 设备已连接并就绪,且符合 LiveStreamingAPI。
  • supportsJPEGImageLiveStreaming 为 true。
  • App 能够在不阻塞流的情况下处理图像和可选音频回调。

API 参考​

框架​

AIBuds.xcframework

导入​

Swift
import AIBuds
import UIKit

属性​

Swift
/// Whether JPEG image live streaming is supported
var supportsJPEGImageLiveStreaming: Bool { get }

实例方法​

Swift
/// Start JPEG image live streaming
/// - Parameters:
///   - sessionStartCompletionHandler: Session start completion handler
///   - jpegDataReceivedHandler: JPEG data received handler
///   - opusDataReceivedHandler: Opus audio data received handler (only called for level-2 Ogg/MJPEG+Opus streams)
///   - sessionFinishHandler: Session finish handler
func startJPEGImageLiveStreaming(
    withSessionStartCompletionHandler sessionStartCompletionHandler: AIBudsLiveStreamingSessionStartCompletionHandler?,
    jpegDataReceivedHandler: AIBudsLiveStreamingJpegDataReceivedHandler?,
    opusDataReceivedHandler: AIBudsLiveStreamingOpusAudioDataReceivedHandler?,
    sessionFinishHandler: AIBudsLiveStreamingSessionFinishHandler?
)

请参阅 startJPEGImageLiveStreaming。

回调值​

Handler值含义
sessionStartCompletionHandlersuccess, error报告直播会话是否启动。
jpegDataReceivedHandlerjpegData以 Data / NSData 提供一个完整 JPEG 图像。
opusDataReceivedHandleropusData, decodedPcmAudioData在兼容的 level-2 流中提供原始 Opus 和可选的解码 PCM 音频。
sessionFinishHandlerisUserInitiatedStop, error报告会话结束结果,以及是否由用户主动停止。

返回值​

该方法没有直接返回值。媒体和生命周期结果通过 Handler 提供。

使用示例​

Swift
guard let streamingDevice = device as? LiveStreamingAPI,
    streamingDevice.supportsJPEGImageLiveStreaming
else { return }

streamingDevice.startJPEGImageLiveStreaming(
    withSessionStartCompletionHandler: { success, error in
        DispatchQueue.main.async {
            self.setStreamingActive(success)
            if let error { self.show(error) }
        }
    },
    jpegDataReceivedHandler: { jpegData in
        // Decode away from the UI update, then assign the image on the main queue.
        guard let image = UIImage(data: jpegData) else { return }
        DispatchQueue.main.async {
            self.imageView.image = image
        }
    },
    opusDataReceivedHandler: { opusData, decodedPcmAudioData in
        guard let decodedPcmAudioData, !decodedPcmAudioData.isEmpty else { return }
        self.consumePCM(decodedPcmAudioData)
    },
    sessionFinishHandler: { userStopped, error in
        DispatchQueue.main.async {
            self.setStreamingActive(false)
            self.handleFinish(userStopped: userStopped, error: error)
        }
    }
)

错误处理​

  • 拒绝无效 JPEG 数据,并保留最后一个有效图像。
  • 音频数据是可选的。仅兼容的流会触发音频回调,且解码 PCM 可能为 nil。
  • 将 sessionStartCompletionHandler 失败视为会话启动失败。
  • 在 sessionFinishHandler 中区分用户停止与意外中断,并在存在时使用 error。
  • 不要在 SDK 提供的回调顺序之外推断丢帧、帧率或顺序保证。

最佳实践​

  1. 避免保留所有 JPEG 帧;替换当前显示图像或使用有界缓冲区。
  2. 保持图像解码和 UI 赋值轻量,避免回调积压。
  3. 新会话开始时清理帧计数器和展示状态。
  4. 离开功能时调用 stopLiveStreaming(),不要只隐藏图像视图。
  5. 不需要音频时,传入 nil 作为 opusDataReceivedHandler。

注意事项​

  • 公开 SDK 没有规定固定 JPEG 分辨率或帧率。
  • JPEG 模式不需要 AIBudsLiveStream 播放类。
  • jpegDataReceivedHandler 提供压缩 JPEG 数据,而不是原始像素缓冲区。
  • RTMP 推流是独立的 AIBudsLiveStream.LiveStreamer 生命周期。使用 configure(outputURL:config:) 配置原始输入模式;仅在推流开始后,才通过 pushJpegFrame(_:) 转发 JPEG 帧,并通过 pushPcmAudio(_:) 转发非空的解码 PCM。