Android 는 Unity3D 에서 RTMP 를 푸 시 하 는 예 를 실현 합 니 다.
1.안 드 로 이 드 네 이 티 브 화면 수집 프로젝트 를 직접 밀봉 하고 유 니 티 에서 인 터 페 이 스 를 제공 하 며 화면 권한 을 받 은 후 화면 데 이 터 를 가 져 와 푸 시 합 니 다.
2.유 니 티 의 창 이나 카메라 데이터 만 가 져 오 면 유 니 티 에서 푸 시 할 원본 데 이 터 를 얻 은 다음 에 네 이 티 브 RTMP 푸 시 인 터 페 이 스 를 패키지 하고 네 이 티 브 SDK 를 호출 하여 데 이 터 를 푸 시 할 수 있 습 니 다.이런 방법 은 수집 해 야 할 데이터 내용 을 사용자 정의 할 수 있 고 네 이 티 브 SDK 가 제공 하 는 인터페이스 에 따라 데이터 도 킹 을 완성 하면 됩 니 다.구체 적 으로 본문 을 참조 하 다.
본 고 는 안 드 로 이 드 플랫폼 의 경우 Unity 환경 에서 의 안 드 로 이 드 플랫폼 RTMP 추 류 를 소개 한다.데이터 수집 은 Unity 에서 이 루어 지고 데이터 인 코딩 푸 시 는 황소 생방송 SDK(공식)안 드 로 이 드 플랫폼 RTMP 생방송 푸 시 SDK 네 이 티 브 라 이브 러 리 가 대외 2 차 로 포 장 된 인 터 페 이 스 를 호출 하여 효율 적 으로 RTMP 푸 시 를 실현 한다.쓸데없는 말 을 많이 하고,먼저 위의 그림 에서 효 과 를 보다.
다음 그림 은 안 드 로 이 드 플랫폼 유 니 티 환경 에서 화면 을 채집 하고 인 코딩 을 RTMP 서버 로 보 낸 다음 에 윈도 플랫폼 재생 기 는 RTMP 스 트림 을 끌 어 와 재생 합 니 다.지연 효 과 를 쉽게 볼 수 있 도록 안 드 로 이 드 엔 드 의 유 니 티 창 에 현재 시간 을 표시 합 니 다.전체 지연 은 밀리초 단위 입 니 다.
데이터 수집 푸 시
유 니 티 데이터 수집 은 상대 적 으로 간단 하여 RGB 24 의 데 이 터 를 쉽게 얻 을 수 있 습 니 다.
texture_ = new Texture2D(video_width_, video_height_, TextureFormat.RGB24, false);
texture_.ReadPixels(new Rect(0, 0, video_width_, video_height_), 0, 0, false);
texture_.Apply();
그리고 texture 를 호출 합 니 다.GetRawTextureData(); 데 이 터 를 가 져 오 면 됩 니 다.데 이 터 를 받 은 후,네 이 티 브 SDK 로 포 장 된 NT 를 호출 합 니 다.PB_U3D_OnCapture VideoRGB24PtrData()인터페이스 로 데이터 배달 이 완료 되 었 습 니 다.
단순 호출 프로 세 스
private void Start()
{
game_object_ = this.gameObject.name;
AndroidJavaClass android_class = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
java_obj_cur_activity_ = android_class.GetStatic<AndroidJavaObject>("currentActivity");
pusher_obj_ = new AndroidJavaObject("com.daniulive.smartpublisher.SmartPublisherUnity3d");
NT_PB_U3D_Init();
//NT_U3D_SetSDKClientKey("", "", 0);
btn_encode_mode_.onClick.AddListener(OnEncodeModeBtnClicked);
btn_pusher_.onClick.AddListener(OnPusherBtnClicked);
btn_mute_.onClick.AddListener(OnMuteBtnClicked);
}
인터페이스 초기 화 완료 후 Push()인터페이스 호출
public void Push()
{
if (is_running)
{
Debug.Log(" ..");
return;
}
if (texture_ != null)
{
UnityEngine.Object.Destroy(texture_);
texture_ = null;
}
video_width_ = Screen.width;
video_height_ = Screen.height;
scale_width_ = (video_width_ + 1) / 2;
scale_height_ = (video_height_ + 1) / 2;
if (scale_width_ % 2 != 0)
{
scale_width_ = scale_width_ + 1;
}
if (scale_height_ % 2 != 0)
{
scale_height_ = scale_height_ + 1;
}
texture_ = new Texture2D(video_width_, video_height_, TextureFormat.RGB24, false);
// url
string url = input_url_.text.Trim();
if (!url.StartsWith("rtmp://"))
{
push_url_ = "rtmp://192.168.0.199:1935/hls/stream1";
}
else
{
push_url_ = url;
}
OpenPusher();
if (pusher_handle_ == 0)
return;
NT_PB_U3D_Set_Game_Object(pusher_handle_, game_object_);
/* ++ ++ */
InitAndSetConfig();
NT_PB_U3D_SetPushUrl(pusher_handle_, push_url_);
/* -- -- */
int flag = NT_PB_U3D_StartPublisher(pusher_handle_);
if (flag == DANIULIVE_RETURN_OK)
{
Debug.Log(" ..");
}
else
{
Debug.LogError(" ..");
}
is_running = true;
}
OpenPusher 호출()
private void OpenPusher()
{
if ( java_obj_cur_activity_ == null )
{
Debug.LogError("getApplicationContext is null");
return;
}
int audio_opt = 1;
int video_opt = 1;
pusher_handle_ = NT_PB_U3D_Open(audio_opt, video_opt, video_width_, video_height_);
if (pusher_handle_ != 0)
Debug.Log("NT_PB_U3D_Open success");
else
Debug.LogError("NT_PB_U3D_Open fail");
}
InitAndSetConfig()
private void InitAndSetConfig()
{
if (is_hw_encode_)
{
int h264HWKbps = setHardwareEncoderKbps(true, video_width_, video_height_);
Debug.Log("h264HWKbps: " + h264HWKbps);
int isSupportH264HWEncoder = NT_PB_U3D_SetVideoHWEncoder(pusher_handle_, h264HWKbps);
if (isSupportH264HWEncoder == 0)
{
Debug.Log("Great, it supports h.264 hardware encoder!");
}
}
else {
if (is_sw_vbr_mode_) //H.264 software encoder
{
int is_enable_vbr = 1;
int video_quality = CalVideoQuality(video_width_, video_height_, true);
int vbr_max_bitrate = CalVbrMaxKBitRate(video_width_, video_height_);
NT_PB_U3D_SetSwVBRMode(pusher_handle_, is_enable_vbr, video_quality, vbr_max_bitrate);
//NT_PB_U3D_SetSWVideoEncoderSpeed(pusher_handle_, 2);
}
}
NT_PB_U3D_SetAudioCodecType(pusher_handle_, 1);
NT_PB_U3D_SetFPS(pusher_handle_, 25);
NT_PB_U3D_SetGopInterval(pusher_handle_, 25*2);
//NT_PB_U3D_SetSWVideoBitRate(pusher_handle_, 600, 1200);
}
ClosePusher()
private void ClosePusher()
{
if (texture_ != null)
{
UnityEngine.Object.Destroy(texture_);
texture_ = null;
}
int flag = NT_PB_U3D_StopPublisher(pusher_handle_);
if (flag == DANIULIVE_RETURN_OK)
{
Debug.Log(" ..");
}
else
{
Debug.LogError(" ..");
}
flag = NT_PB_U3D_Close(pusher_handle_);
if (flag == DANIULIVE_RETURN_OK)
{
Debug.Log(" ..");
}
else
{
Debug.LogError(" ..");
}
pusher_handle_ = 0;
NT_PB_U3D_UnInit();
is_running = false;
}
테스트 에 편리 하도록 Update()는 현재 시간 을 갱신 합 니 다:
private void Update()
{
//
hour = DateTime.Now.Hour;
minute = DateTime.Now.Minute;
millisecond = DateTime.Now.Millisecond;
second = DateTime.Now.Second;
year = DateTime.Now.Year;
month = DateTime.Now.Month;
day = DateTime.Now.Day;
GameObject.Find("Canvas/Panel/LableText").GetComponent<Text>().text = string.Format("{0:D2}:{1:D2}:{2:D2}:{3:D2} " + "{4:D4}/{5:D2}/{6:D2}", hour, minute, second, millisecond, year, month, day);
}
관련 이벤트 처리
public void onNTSmartEvent(string param)
{
if (!param.Contains(","))
{
Debug.Log("[onNTSmartEvent] android ");
return;
}
string[] strs = param.Split(',');
string player_handle =strs[0];
string code = strs[1];
string param1 = strs[2];
string param2 = strs[3];
string param3 = strs[4];
string param4 = strs[5];
Debug.Log("[onNTSmartEvent] code: 0x" + Convert.ToString(Convert.ToInt32(code), 16));
String publisher_event = "";
switch (Convert.ToInt32(code))
{
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_STARTED:
publisher_event = " ..";
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_CONNECTING:
publisher_event = " ..";
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_CONNECTION_FAILED:
publisher_event = " ..";
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_CONNECTED:
publisher_event = " ..";
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_DISCONNECTED:
publisher_event = " ..";
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_STOP:
publisher_event = " ..";
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_RECORDER_START_NEW_FILE:
publisher_event = " : " + param3;
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_ONE_RECORDER_FILE_FINISHED:
publisher_event = " : " + param3;
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_SEND_DELAY:
publisher_event = " : " + param1 + " :" + param2;
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_CAPTURE_IMAGE:
publisher_event = " : " + param1 + " :" + param3;
if (Convert.ToInt32(param1) == 0)
{
publisher_event = publisher_event + " ..";
}
else
{
publisher_event = publisher_event + " ..";
}
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUBLISHER_RTSP_URL:
publisher_event = "RTSP URL: " + param3;
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUSH_RTSP_SERVER_RESPONSE_STATUS_CODE:
publisher_event = "RTSP status code received, codeID: " + param1 + ", RTSP URL: " + param3;
break;
case EVENTID.EVENT_DANIULIVE_ERC_PUSH_RTSP_SERVER_NOT_SUPPORT:
publisher_event = " RTSP , RTSP URL: " + param3;
break;
}
Debug.Log(publisher_event);
}
총결산위 절 차 를 통 해 Unity 환경 에서 화면 이나 카메라 데 이 터 를 구현 하고 밀리초 단위 로 체험 하 는 RTMP 푸 시 와 재생 을 실현 할 수 있 으 며 관심 있 는 개발 자 는 참고 할 수 있 습 니 다.
이상 은 안 드 로 이 드 가 유 니 티 3D 에서 RTMP 푸 시 를 실현 하 는 예제 의 상세 한 내용 입 니 다.안 드 로 이 드 가 유 니 티 3D 에서 RTMP 푸 시 를 실현 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.