← Alle Erweiterungen

Native Erweiterung · Flaggschiff

KlugMedia

com.klug.media

KEIN APM NÖTIG. Herunterladen und loslegen. Einfacher geht es nicht.

Kamera, bidirektionale Sprache und Hardware-Echounterdrückung in einer nativen Sitzung, mit Senden und Empfangen von H.264 und Opus über Standard-RTMP.

iOSAndroidmacOS Im Produktiveinsatz Ab €99 / Jahr · Kaufen

Überblick

AIR bietet derzeit keine aktuelle Implementierung für Echtzeit-Medien-Streaming. KlugMedia ergänzt sie als native Erweiterung. Kamera, Mikrofon, Encoder und Echounterdrückung laufen gemeinsam in einer nativen Sitzung, und ActionScript sendet nur Befehle und empfängt Status.

Video wird als H.264 gesendet und empfangen, Sprache als Opus, beides über Standard-RTMP. Empfangenes Video wird nativ über der AIR-Stage gezeichnet und bleibt dadurch auch auf älteren Geräten scharf und flüssig.

KlugMedia ist in unseren Apps täglich im Einsatz, unserem Praxisbeweis, im App Store, bei Google Play und auf dem Mac.

Funktionen

  • Eigenständig: eine ANE, keine Kernbibliothek und keine abhängigen ANEs, die Sie ergänzen müssten
  • Kameraaufnahme und H.264-Publishing in einer nativen Sitzung
  • Nativer H.264-Empfang und native Anzeige, seitenverhältnistreu, mit Zuschneiden zum Füllen und Rotation
  • Bidirektionale Opus-Sprache mit Hardware-Echounterdrückung, beide Seiten sprechen gleichzeitig
  • Native Kameravorschau, Kamerawechsel, Taschenlampe und Zoom
  • Schnappschüsse direkt aus dem Kamerabild
  • MP4-Aufzeichnung von Live-Streams auf dem Klug Streaming Server, mit Bild und Ton
  • Automatische Bitratenanpassung in schwachen Netzen
  • Adaptiver Sprachpuffer, der WLAN-Aussetzer überbrückt und von selbst zu niedriger Verzögerung zurückkehrt
  • Auf dem Mac: Wechsel zwischen eingebauter Kamera und USB-Kameras in etwa einer Sekunde
  • Standard-RTMP, daher kompatibel mit gewöhnlichen Medienservern

Streaming-Server

KlugMedia wird mit der passenden Server-Software geliefert, gemeinsam mit der Erweiterung entwickelt und auf AIR-Apps abgestimmt: Stream-Verwaltung, zuverlässige Wiederverbindung, das Relay für bidirektionale Sprache, MP4-Aufzeichnung und Live-Wiedergabe im Webbrowser.

Der Server wird auf der Übersichtsseite beschrieben: Streaming-Server.

Unterstützte Plattformen

iOS arm64
Android arm64 · armv7
macOS Apple Silicon · Intel
iPad-Apps auf dem Mac Apple Silicon · macOS 26 und 27

iPad-Apps auf dem Mac

Auf Macs mit Apple Silicon kann der iOS-Build einer AIR-App als iPad-App laufen. KlugMedia unterstützt diesen Modus mit Kamera, Live-Video und bidirektionaler Sprache, einschließlich der eingebauten FaceTime-Kamera und externer USB-Kameras. Ein Build bedient iPhone, iPad und Mac.

Bereit für iOS 27 und macOS 27

KlugMedia ist getestet auf iOS 27, iPadOS 27 und macOS 27, auf iPhone, iPad, MacBook und Mac mini, und weiterhin auf iOS 17. Highlights dieser Version:

  • Gehärteter Empfangspfad: Das Stoppen und Neustarten eines Live-Streams ist jederzeit sicher, auch bei dem Timing von iOS 27
  • Stabile Kameravorschau unter macOS 27 für iPad-Apps auf dem Mac, während die Kamera startet, stoppt oder wechselt
  • Korrekte Ausrichtung auf jedem Mac: Eingebaute und USB-Kameras stehen in der Vorschau und beim Empfänger aufrecht, unter macOS 26 und 27
  • Schneller Kamerawechsel auf dem Mac zwischen der FaceTime-Kamera und USB-Kameras, in etwa einer Sekunde
  • Klare Sprache im Laptop-WLAN: Ein adaptiver Puffer fängt die kurzen WLAN-Bursts ab, die bei MacBooks typisch sind, und schrumpft wieder, wenn das Netz ruhig ist

Erste Schritte

Fügen Sie die Erweiterung Ihrem Application Descriptor hinzu:

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

Fordern Sie vor dem ersten Start die Kamera- und Mikrofonberechtigung an. Danach besitzt die Erweiterung die Aufnahme: Öffnen Sie nicht gleichzeitig eine AIR-Camera oder ein AIR-Microphone.

Codebeispiele

Fünf vollständige Abläufe, entnommen der API, die täglich in unseren Apps läuft. Jeder Aufruf kehrt sofort zurück; Ergebnisse kommen als StatusEvents an. Vollständige Dokumentation →

1 · Kamera-Stream senden
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 · Empfangen und dem Layout folgen
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 · Bidirektionale Sprache mit Echounterdrückung
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 );
}
Die Sprachpakete werden als Datennachrichten auf einem eigenen Streampaar übertragen. Der Klug Streaming Server leitet sie sofort einsatzbereit weiter; andere RTMP-Server müssen NetStream.send an die Abonnenten weiterleiten.
4 · Vorschau, Kamerawechsel, Taschenlampe, Zoom, Schnappschuss
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 · Sauberer Stopp und Neustart
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-Übersicht

isSupportedTrue, wenn die native Mediensitzung verfügbar ist.
startPublish(…)Startet die Kamera und sendet H.264 über RTMP: Größe, fps, Bitrate, Keyframe-Intervall, Kamera, optionale RTMP-Anmeldung.
stopPublish()Beendet das Senden; die Kamera wird freigegeben, sofern die Vorschau nicht noch angezeigt wird.
startReceive(…)Spielt einen entfernten Stream nativ in einem Rechteck der Stage ab: Seitenverhältnis einpassen oder Zuschneiden zum Füllen mit Rotation (Strecken unter Android).
setReceiveFrame(x, y, w, h)Verschiebt und skaliert das native Video, für Rotation, faltbare Smartphones und Vollbild.
stopReceive()Beendet die Wiedergabe und entfernt die native Ansicht.
showPreview(…) / hidePreview()Native Kameravorschau über der Stage, allein oder neben einem laufenden Stream.
switchCamera()Wechselt während des Streamings zur nächsten Kamera: vorne und hinten auf iPhone und iPad, eingebaute und USB-Kameras auf dem Mac.
setTorch(on) / hasTorchKameralicht während des Streamings und ob das Gerät eines hat.
setCameraZoom(step)Echter Kamerazoom unter iOS und Android, 0..8 für 1,0x bis 2,0x; der Stream wird mitgezoomt.
setVideoBitrate(kbps)Ändert die Encoder-Bitrate im laufenden Betrieb.
captureSnapshot(w, h)Speichert ein JPEG aus dem Live-Kamerabild.
isiOSAppOnMacTrue, wenn der iOS-Build als iPad-App auf einem Mac mit Apple Silicon läuft.
OpusVoiceBridgeBidirektionale Sprache: Start, Stopp, Echounterdrückung, Lautsprecher, Verstärkung, Wiedergabepuffer.
Red5OpusTransportÜberträgt die Opus-Pakete über Ihre RTMP-Verbindung auf zwei dedizierten Streams.

Status-Ereignisse

cameraStatusconnecting · connected · disconnected · failed:<reason> · authError:<reason> · newBitrate:<rate> · authSuccess (Android)
receiveStatusplaying · firstFrame · disconnected · streamEnded und failed:<reason> (iOS, macOS)
snapshotStatussaved:<path> · failed:<reason>

KlugMedia kaufen

Eine Jahreslizenz für eine AIR-Anwendung, mit allen Updates für 12 Monate. Nach der Zahlung erhalten Sie die Erweiterung, die ActionScript-Bibliothek und die Dokumentation per E-Mail, in der Regel innerhalb eines Werktags. Lizenz und Bedingungen

Simple
€99 / Jahr
  • Lizenz für eine AIR-Anwendung
  • Alle Updates für 12 Monate
  • Kein Support
Simple kaufen
Standard
€349 / Jahr
  • Lizenz für eine AIR-Anwendung
  • Alle Updates für 12 Monate
  • Antwort per E-Mail innerhalb von 7 Tagen
Standard kaufen
Priority
€699 / Jahr
  • Lizenz für eine AIR-Anwendung
  • Alle Updates für 12 Monate
  • Antwort per E-Mail innerhalb von 48 Stunden
Priority kaufen
Die Steuern werden an der Kasse von Link (Stripe) berechnet. Die Application-ID Ihrer AIR-App geben Sie beim Bezahlen ein.

Voraussetzungen

AIR SDK51.x (HARMAN)
iOSiOS 17 oder neuer
AndroidAndroid 6.0 (API 23) oder neuer
macOSmacOS 11 oder neuer
iPad-Apps auf dem MacApple Silicon, macOS 26 oder neuer
BerechtigungenKamera und Mikrofon
ServerJeder RTMP-Server; empfohlen wird der passende Klug Streaming Server