← すべての拡張機能

ネイティブ拡張機能 · フラッグシップ

KlugMedia

com.klug.media

APMは不要。ダウンロードしてすぐに使えます。これ以上シンプルにはできません。

カメラ、双方向音声、ハードウェアエコーキャンセリングをひとつのネイティブセッションに統合し、標準の RTMP で H.264 と Opus を配信・受信します。

iOSAndroidmacOS 本番稼働中 年額€99から · 購入

概要

現在、AIR にはリアルタイムメディアストリーミングの最新の実装がありません。KlugMedia はそれをネイティブ拡張機能として追加します。カメラ、マイク、エンコーダー、エコーキャンセリングがひとつのネイティブセッションでまとめて動作し、ActionScript はコマンドを送信してステータスを受け取るだけです。

映像は H.264、音声は Opus で、どちらも標準の RTMP で配信・受信されます。受信した映像は AIR ステージの上にネイティブで描画されるため、古いデバイスでも鮮明でなめらかに表示されます。

KlugMedia は、App Store、Google Play、Mac で、実証の場である当社のアプリにおいて毎日使われています。

機能

  • 自己完結型:ANE 1つで完結し、コアライブラリや依存 ANE の追加は不要
  • ひとつのネイティブセッションでのカメラキャプチャと H.264 配信
  • ネイティブの H.264 受信と表示。アスペクト比を維持し、クロップ表示と回転にも対応
  • ハードウェアエコーキャンセリング付きの双方向 Opus 音声。双方が同時に話せます
  • ネイティブのカメラプレビュー、カメラ切り替え、トーチ、ズーム
  • カメラ映像から直接スナップショットを取得
  • Klug ストリーミングサーバー上でのライブストリームの MP4 録画(映像と音声)
  • 低速なネットワークでのビットレート自動調整
  • Wi-Fi の瞬断を吸収し、自動的に低遅延へ戻る適応型の音声バッファ
  • Mac では、内蔵カメラと USB カメラを約1秒で切り替え
  • 標準の RTMP を使用するため、一般的なメディアサーバーでも動作

ストリーミングサーバー

KlugMedia には、拡張機能と一緒に開発され、AIR アプリ向けに調整された専用のサーバーソフトウェアが付属します。ストリーム管理、信頼性の高い再接続、双方向音声リレー、MP4 録画、Webブラウザでのライブ視聴に対応します。

サーバーについては概要ページをご覧ください:ストリーミングサーバー。

対応プラットフォーム

iOS arm64
Android arm64 · armv7
macOS Apple silicon · Intel
Mac 上の iPad アプリ Apple silicon · macOS 26 および 27

Mac 上の iPad アプリ

Apple シリコン搭載の Mac では、AIR アプリの iOS ビルドを iPad アプリとして実行できます。KlugMedia は、内蔵の FaceTime カメラや外付け USB カメラを含め、カメラ、ライブ映像、双方向音声でこのモードに対応しています。1つのビルドで iPhone、iPad、Mac に対応します。

iOS 27 と macOS 27 に対応

KlugMedia は、iPhone、iPad、MacBook、Mac mini 上の iOS 27、iPadOS 27、macOS 27、そして引き続き iOS 17 でもテスト済みです。このリリースのハイライト:

  • 強化された受信パス:iOS 27 のタイミングでも、ライブストリームの停止と再開をいつでも安全に行えます
  • macOS 27 で安定したカメラプレビュー:Mac 上の iPad アプリで、カメラの開始・停止・切り替え中も安定します
  • すべての Mac で正しい向き:内蔵カメラと USB カメラが、macOS 26 と 27 のプレビューと受信側で正立して表示されます
  • Mac での高速なカメラ切り替え:FaceTime カメラと USB カメラの間を約1秒で切り替えられます
  • ノートPCの Wi-Fi でもクリアな音声:適応型バッファが MacBook に特有の短い Wi-Fi バーストを吸収し、ネットワークが落ち着くと元の大きさに戻ります

はじめに

アプリケーション記述子に拡張機能を追加します:

app.xml
<extensions>
    <extensionID>com.klug.media</extensionID>
</extensions>

最初の起動の前に、カメラとマイクの権限をリクエストしてください。その後は拡張機能がキャプチャを管理しますので、AIR の Camera や Microphone を同時に開かないでください。

コード例

当社のアプリで毎日稼働している API から取り出した、5つの完全なフローです。すべての呼び出しは即座に返り、結果は StatusEvent として届きます。完全なドキュメント →

1 · カメラストリームを配信する
Station.as
import com.klug.petcam.camera.CameraStreamANE;
import flash.events.StatusEvent;

var media:CameraStreamANE = CameraStreamANE.instance;
media.addEventListener( StatusEvent.STATUS, onMedia );

if ( media.isSupported )
{
    // camera, H.264 encoder and RTMP in one native session
    media.startPublish( "rtmp://your.server:1935/live", "station-1",
                        640, 480,     // size
                        12, 800,      // fps, kbps
                        2,            // keyframe every 2 s: fast start at the viewer
                        CameraStreamANE.CAMERA_BACK );
}

function onMedia( e:StatusEvent ):void
{
    if ( e.code != CameraStreamANE.STATUS_EVENT ) return;
    if ( e.level == "connected" )             showLive();
    else if ( e.level.indexOf( "failed:" ) == 0 )  retryLater( e.level.substr( 7 ) );
    else if ( e.level.indexOf( "authError:" ) == 0 ) askForLogin();
}
2 · 受信してレイアウトに追従する
Viewer.as
// the video is decoded natively and drawn in a view above the stage (pixels)
media.startReceive( "rtmp://your.server:1935/live", "station-1",
                    0, 80, stage.stageWidth, stage.stageHeight - 160,
                    0, CameraStreamANE.RECEIVE_FIT );   // or RECEIVE_CROPFILL

media.addEventListener( StatusEvent.STATUS, function( e:StatusEvent ):void {
    if ( e.code == "receiveStatus" && e.level == "firstFrame" ) hideSpinner();
});

// rotation, a folding phone, fullscreen: move the native view with the stage
stage.addEventListener( Event.RESIZE, function( e:Event ):void {
    media.setReceiveFrame( 0, 80, stage.stageWidth, stage.stageHeight - 160 );
});
3 · エコーキャンセリング付き双方向音声
Voice.as
import com.klug.petcam.audioecho.*;

var voice:OpusVoiceBridge = new OpusVoiceBridge( new NativeOpusCodec(), 48000, 1, 960 );
var link:Red5OpusTransport;

var nc:NetConnection = new NetConnection();
nc.addEventListener( NetStatusEvent.NET_STATUS, function( e:NetStatusEvent ):void {
    if ( e.info.code == "NetConnection.Connect.Success" ) startVoice();
});
nc.connect( "rtmp://your.server:1935/live" );

function startVoice():void
{
    link = new Red5OpusTransport( nc );
    link.addEventListener( OpusPacketEvent.PACKET, function( e:OpusPacketEvent ):void {
        voice.playRemoteOpus( e.packet );            // decode and play the other side
    });
    link.start( "voice_me", "voice_other" );     // my stream, the other side's stream

    voice.setVoiceProcessing( true );             // hardware echo cancellation
    EchoCancellationANE.instance.setDuck( false ); // both sides may talk at once
    voice.start();
    addEventListener( Event.ENTER_FRAME, sendVoice );
}

function sendVoice( e:Event ):void
{
    var packet:ByteArray;
    while ( ( packet = voice.readLocalOpus() ) != null )   // every finished 20 ms frame
        link.sendPacket( packet );
}
音声パケットは、専用のストリームペア上でデータメッセージとして送られます。Klug ストリーミングサーバーは標準でこれを中継します。他の RTMP サーバーでは、NetStream.send をサブスクライバーに転送する必要があります。
4 · プレビュー、カメラ切り替え、トーチ、ズーム、スナップショット
Controls.as
media.showPreview( 20, 100, 320, 240, CameraStreamANE.CAMERA_FRONT );   // aiming preview

media.switchCamera();               // front / back, or built-in / USB camera on the Mac
if ( media.hasTorch ) media.setTorch( true );
media.setCameraZoom( 4 );           // 0..8 = 1.0x..2.0x, the stream is zoomed too
media.setVideoBitrate( 500 );       // change the bitrate while live

media.addEventListener( StatusEvent.STATUS, function( e:StatusEvent ):void {
    if ( e.code == "snapshotStatus" && e.level.indexOf( "saved:" ) == 0 )
        showPhoto( e.level.substr( 6 ) );                // absolute path of the JPEG
});
media.captureSnapshot( 640, 480 );

media.hidePreview();   // native views sit above the stage: hide them before dialogs
5 · クリーンな停止と再開
Session.as
function stopAll():void
{
    removeEventListener( Event.ENTER_FRAME, sendVoice );
    voice.stop();
    link.stop();
    media.stopReceive();
    media.stopPublish();    // always stop before publishing the same name again
}

// safe at any moment, also while a stream is still connecting
stopAll();
media.startPublish( "rtmp://your.server:1935/live", "station-1" );

API 概要

isSupportedネイティブメディアセッションが利用可能な環境で true になります。
startPublish(…)カメラを起動し、RTMP で H.264 を配信します:サイズ、fps、ビットレート、キーフレーム間隔、カメラ、任意の RTMP ログイン。
stopPublish()配信を停止します。プレビューが表示中でない限り、カメラは解放されます。
startReceive(…)リモートストリームをステージ上の矩形内でネイティブ再生します:アスペクト比を維持、または回転付きのクロップ表示(Android では引き伸ばし)。
setReceiveFrame(x, y, w, h)回転、折りたたみ式スマートフォン、全画面表示のために、ネイティブ映像を移動・リサイズします。
stopReceive()再生を停止し、ネイティブビューを削除します。
showPreview(…) / hidePreview()ステージ上にネイティブのカメラプレビューを表示します。単独でも、ライブ配信と並べても使えます。
switchCamera()ストリーミング中に次のカメラへ切り替えます:iPhone と iPad では前面と背面、Mac では内蔵カメラと USB カメラ。
setTorch(on) / hasTorchストリーミング中のカメラライトと、デバイスにライトがあるかどうか。
setCameraZoom(step)iOS と Android での実際のカメラズーム。0〜8 が 1.0x〜2.0x に対応し、ストリームもズームされます。
setVideoBitrate(kbps)ライブ中にエンコーダーのビットレートを変更します。
captureSnapshot(w, h)ライブのカメラ映像から JPEG を保存します。
isiOSAppOnMaciOS ビルドが Apple シリコン搭載 Mac 上で iPad アプリとして実行されている場合に true になります。
OpusVoiceBridge双方向音声:開始、停止、エコーキャンセリング、スピーカー、ゲイン、再生バッファ。
Red5OpusTransport既存の RTMP 接続上の2本の専用ストリームで Opus パケットを運びます。

ステータスイベント

cameraStatusconnecting · connected · disconnected · failed:<reason> · authError:<reason> · newBitrate:<rate> · authSuccess (Android)
receiveStatusplaying · firstFrame · disconnected · streamEnded および failed:<reason>(iOS、macOS)
snapshotStatussaved:<path> · failed:<reason>

KlugMedia を購入

AIR アプリケーション1つ分の年間ライセンスで、12か月間のすべてのアップデートが含まれます。お支払い後、拡張機能、ActionScript ライブラリ、ドキュメントをメールでお送りします(通常は1営業日以内)。ライセンスと条件

シンプル
€99 / 年
  • AIR アプリケーション1つ分のライセンス
  • 12か月間のすべてのアップデート
  • サポートなし
シンプルを購入
スタンダード
€349 / 年
  • AIR アプリケーション1つ分のライセンス
  • 12か月間のすべてのアップデート
  • 7日以内にメールで回答
スタンダードを購入
プライオリティ
€699 / 年
  • AIR アプリケーション1つ分のライセンス
  • 12か月間のすべてのアップデート
  • 48時間以内にメールで回答
プライオリティを購入
税金は Link(Stripe)によりチェックアウト時に計算されます。チェックアウト時に、AIR アプリのアプリケーションIDを入力してください。

動作要件

AIR SDK51.x(HARMAN)
iOSiOS 17 以降
AndroidAndroid 6.0(API 23)以降
macOSmacOS 11 以降
Mac 上の iPad アプリApple silicon、macOS 26 以降
権限カメラとマイク
サーバー任意の RTMP サーバー。対応する Klug ストリーミングサーバーを推奨