メインコンテンツまでスキップ

JPEG 画像ライブストリーミング

デバイスの JPEG ライブストリーミングモードを開始し、SDK から届く完全な JPEG 画像を順次描画します。対応する level-2 ストリームでは、Opus 音声と、利用可能な場合はデコード済み PCM データも受信できます。

前提条件​

  • デバイスが接続済みで使用可能な状態にあり、LiveStreamingAPI に準拠していること。
  • supportsJPEGImageLiveStreaming が true であること。
  • ストリームをブロックせず、画像と任意の音声コールバックを処理できること。

API Reference​

フレームワーク​

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 を参照してください。

コールバック値​

ハンドラー値意味
sessionStartCompletionHandlersuccess, errorライブストリーミングセッションの開始結果。
jpegDataReceivedHandlerjpegData完全な JPEG 画像 1 枚を Data / NSData として通知。
opusDataReceivedHandleropusData, decodedPcmAudioData対応する level-2 ストリームで、元の Opus データと、利用可能な場合はデコード済み PCM 音声を通知。
sessionFinishHandlerisUserInitiatedStop, errorセッションの最終結果と、ユーザー操作による停止かどうかを通知。

戻り値​

このメソッドは値を直接返しません。メディアとライフサイクルの結果は各ハンドラーから通知されます。

使用例​

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. 機能を終了するときは画像 View を隠すだけでなく、stopLiveStreaming() を呼び出します。
  5. 音声が不要な場合は、nil を opusDataReceivedHandler に渡します。

注意事項​

  • 公開 SDK では JPEG の固定解像度やフレームレートを規定していません。
  • JPEG モードでは AIBudsLiveStream の再生クラスは不要です。
  • jpegDataReceivedHandler が提供するのは圧縮済み JPEG データであり、未圧縮のピクセルバッファではありません。
  • RTMP 配信は独立した AIBudsLiveStream.LiveStreamer のライフサイクルで管理します。configure(outputURL:config:) で直接入力モードを設定し、配信開始後に限り、JPEG フレームを pushJpegFrame(_:)、空でないデコード済み PCM を pushPcmAudio(_:) へ渡します。