Фон: я создаю приложение, в котором я использую Dji SDK для iOS. Я интегрировал SDK и могу зарегистрировать приложение DJI. Я могу получить соединение с дроном и название модели.
Затем я собираюсь запустить видеопоток на дрон с помощью SDK и записать его на экране мобильного телефона. Но есть поворот.
Настройка: Мое приложение основано на единстве и намеревается использовать некоторые функции единства. Следовательно, данные, которые я получаю от dji sdk по этому методу
-(void)videoFeed:(nonnull DJIVideoFeed *)videoFeed didUpdateVideoData:(nonnull NSData *)videoData{
[[DJIVideoPreviewer instance] push:(uint8_t *)videoData.bytes length:(int)videoData.length];
, необходимо отправить в единицу, где я бы отобразил их в Texture2d, предоставленном единством.
Проблема: I Я не могу преобразовать видеоданные, представленные в приведенном выше методе, и отправить их в формате, который единство может понять и отобразить в объекте Texture2d.
Я получил несколько предложений, связанных с _GetNativeTexturePtr и MTLTexture, но это не сработало для me.
Цель: передавать NSData * videoData из iOS в объект Unity Texture2d при каждом вызове функции update () и отображать его там.
Любая помощь приветствуется, спасибо!
Чтобы дать более четкое представление, я делюсь, как я сделал в Android (он работает в android):
static Texture2D videoStreamTexture;
protected override Texture2D StartVideoStream_Native() {
int width = droneNativeObject.Get<int>("width");
int height = droneNativeObject.Get<int>("height");
if (videoStreamTexture == null)
videoStreamTexture = new Texture2D(width, height, TextureFormat.RGBA32, false);
droneNativeObject.Call("StartStream", videoStreamTexture.GetNativeTexturePtr().ToInt32()/*, 1920, 1088*/);
return videoStreamTexture;
}
protected override void StopVideoStream_Native() {
droneNativeObject.Call("StopStream");
/* if (videoStreamTexture != null) {
UnityEngine.Object.DestroyImmediate(videoStreamTexture);
videoStreamTexture = null;
}*/
}
public override void Update() {
base.Update();
if (IsStreaming && droneNativeObject != null &&videoStreamTexture != null) {
var frame = droneNativeObject.Call<AndroidJavaObject>("GetCameraFrame");
if (frame == null)
return;
byte[] bytes = frame.Get<byte[]>("jpegFrame");
int width = frame.Get<int>("width");
int height = frame.Get<int>("height");
if (bytes != null && bytes.Length > 0) {
//Debug.Log("texture size: width " + videoStreamTexture.width + " height " + videoStreamTexture.height);
videoStreamTexture.LoadRawTextureData(bytes);
videoStreamTexture.Apply(false);
}
}
}
Собственный Android код:
public int width = 1280;
public int height = 720;
public void StartStream(int textureId/*,int textureWidth, int textureHeight*/){
if(isStreaming)
return;
isStreaming = true;
cameraFrameIndex = -1;
lastPublishedCameraFrameIndex = -1;
if(surfaceTexture == null)
surfaceTexture = new SurfaceTexture(textureId);
//surfaceTexture.setDefaultBufferSize(width, height);
SetCameraToRecordMode();
if(codecManager == null)
codecManager = new DJICodecManager(activity.getBaseContext(), surfaceTexture, width, height);
VideoFeeder.getInstance().provideTranscodedVideoFeed().addVideoDataListener(videoDataListener);
}
public final class CameraFrame{
public byte[] jpegFrame;
public int width;
public int height;
public CameraFrame(){
}
public CameraFrame(byte[] frameData, int width, int height){
this.jpegFrame = frameData;
this.width = width;
this.height = height;
}
}
CameraFrame jpegFrame;
public CameraFrame FGetCameraFrame(){
if(!isStreaming || lastPublishedCameraFrameIndex == cameraFrameIndex){
return null;
}
lastPublishedCameraFrameIndex = cameraFrameIndex;
byte[] bytes = codecManager.getRgbaData(width, height);
return new CameraFrame(bytes, width, height);
}
}