← 모든 확장

네이티브 확장 · 플래그십

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 하나로 충분하며, 코어 라이브러리나 의존성 ANE를 추가할 필요가 없음
  • 하나의 네이티브 세션에서 카메라 캡처 및 H.264 퍼블리싱
  • 네이티브 H.264 수신 및 표시: 비율 유지, 크롭 채우기, 회전 지원
  • 하드웨어 에코 캔슬링을 갖춘 양방향 Opus 음성, 양쪽이 동시에 말해도 문제없음
  • 네이티브 카메라 미리보기, 카메라 전환, 토치, 줌
  • 카메라 이미지에서 바로 촬영하는 스냅샷
  • Klug 스트리밍 서버에서의 라이브 스트림 MP4 녹화, 영상과 소리 포함
  • 불안정한 네트워크에서의 자동 비트레이트 조정
  • Wi-Fi 끊김을 흡수하고 스스로 낮은 지연으로 돌아오는 적응형 음성 버퍼
  • Mac에서 내장 카메라와 USB 카메라를 약 1초 만에 전환
  • 표준 RTMP이므로 일반적인 미디어 서버와 함께 동작

스트리밍 서버

KlugMedia에는 확장과 함께 개발되어 AIR 앱에 맞게 조정된 매칭 서버 소프트웨어가 포함됩니다. 스트림 처리, 안정적인 재연결, 양방향 음성 릴레이, MP4 녹화, 웹 브라우저 실시간 시청을 지원합니다.

서버에 대한 설명은 개요 페이지에 있습니다: 스트리밍 서버.

지원 플랫폼

iOS arm64
Android arm64 · armv7
macOS Apple silicon · Intel
Mac의 iPad 앱 Apple silicon · macOS 26 및 27

Mac의 iPad 앱

Apple silicon을 탑재한 Mac에서는 AIR 앱의 iOS 빌드를 iPad 앱으로 실행할 수 있습니다. KlugMedia는 내장 FaceTime 카메라와 외장 USB 카메라를 포함해 카메라, 실시간 영상, 양방향 음성으로 이 모드를 지원합니다. 하나의 빌드로 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에서 올바른 방향: macOS 26 및 27에서 내장 카메라와 USB 카메라가 미리보기와 수신 측 모두에서 똑바로 표시됩니다
  • Mac에서 빠른 카메라 전환: FaceTime 카메라와 USB 카메라 사이를 약 1초 만에 전환합니다
  • 노트북 Wi-Fi에서도 선명한 음성: 적응형 버퍼가 MacBook 특유의 짧은 Wi-Fi 버스트를 흡수하고, 네트워크가 안정되면 다시 줄어듭니다

시작하기

애플리케이션 디스크립터에 확장을 추가합니다:

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

첫 시작 전에 카메라와 마이크 권한을 요청하세요. 이후 확장이 캡처를 소유하므로, 동시에 AIR Camera 또는 Microphone을 열지 마세요.

코드 예제

저희 앱에서 매일 실행되는 API에서 가져온 다섯 가지 완전한 흐름입니다. 모든 호출은 즉시 반환되며, 결과는 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에서의 실제 카메라 줌, 1.0x~2.0x에 해당하는 0..8, 스트림도 함께 줌됩니다.
setVideoBitrate(kbps)라이브 중에 인코더 비트레이트를 변경합니다.
captureSnapshot(w, h)라이브 카메라 이미지에서 JPEG를 저장합니다.
isiOSAppOnMaciOS 빌드가 Apple silicon Mac에서 iPad 앱으로 실행될 때 true입니다.
OpusVoiceBridge양방향 음성: 시작, 중지, 에코 캔슬링, 스피커, 게인, 재생 버퍼.
Red5OpusTransportRTMP 연결 위의 전용 스트림 두 개로 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 스트리밍 서버 권장