gpt4 book ai didi

java - 使用 DJI Android SDK LiveStreamManager 直播无人机摄像头有很大的延迟。使用 SampleCode 却没有,我错过了什么?

转载 作者:行者123 更新时间:2023-12-01 22:33:40 24 4
gpt4 key购买 nike

我使用 DJI SDK 创建了一个 Android 应用程序。我已按照说明进行操作,基本上复制了 DJI 示例代码( https://github.com/dji-sdk/Mobile-SDK-Android/blob/master/Sample%20Code/app/src/main/java/com/dji/sdk/sample/demo/camera/LiveStreamView.java )中的代码,因为它工作正常。

启动 Connectivity Activity (注册 SDK 并连接到 Mavic 2 Zoom 无人机)后,另一个 Activity 出现,处理到 RTMP 服务器的实时流媒体传输。当使用示例代码时,流式传输到同一个 RTMP 服务器,它没有延迟,但当使用我的应用程序时,它有 15 秒的延迟。我不明白为什么,我使用相同的组件。唯一的区别是我将相机焦点设置为最大,但我在示例代码中做了同样的事情,所以它不会引起任何问题。还使用与示例中相同的 VideoFeedView。

public class MainActivity extends Activity implements View.OnClickListener {

private static final String TAG = MainActivity.class.getName();

private String liveShowUrl = "rtmp://192.168.00.00/live";

private VideoFeedView primaryVideoFeedView;
private VideoFeedView fpvVideoFeedView;
private EditText showUrlInputEdit;

private Button startLiveShowBtn;
private Button enableVideoEncodingBtn;
private Button disableVideoEncodingBtn;
private Button stopLiveShowBtn;
private Button soundOnBtn;
private Button soundOffBtn;
private Button isLiveShowOnBtn;
private Button showInfoBtn;
private Button showLiveStartTimeBtn;
private Button showCurrentVideoSourceBtn;
private Button changeVideoSourceBtn;
private Camera camera;

private LiveStreamManager.OnLiveChangeListener listener;
private LiveStreamManager.LiveStreamVideoSource currentVideoSource = LiveStreamManager.LiveStreamVideoSource.Primary;

private CommonCallbacks.CompletionCallback focusSetCompletionCallback = new CommonCallbacks.CompletionCallback() {
@Override
public void onResult(DJIError djiError) {
Log.d(TAG, "Camera focus is set to manual");
Toast.makeText(getApplicationContext(), "camera focus set to manual", Toast.LENGTH_SHORT).show();
}
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
initListener();

camera = DronifyApplication.getCameraInstance();
camera.getFocusRingValueUpperBound(new CommonCallbacks.CompletionCallbackWith<Integer>() {
@Override
public void onSuccess(Integer integer) {
Toast.makeText(getApplicationContext(), "UPPER IS: " + integer.toString(),Toast.LENGTH_LONG).show();
Log.d(TAG, "UPPER IS: " + integer.toString());
}

@Override
public void onFailure(DJIError djiError) {
Toast.makeText(getApplicationContext(), "UPPER IS NOT SUPPORTED", Toast.LENGTH_LONG).show();

}
});
camera.setFocusMode(SettingsDefinitions.FocusMode.MANUAL, focusSetCompletionCallback);
if (camera.isAdjustableFocalPointSupported()) {
camera.setFocusRingValue(65, new CommonCallbacks.CompletionCallback() {
@Override
public void onResult(DJIError djiError) {
Log.i(TAG, "set focus ring value to max");
Toast.makeText(getApplicationContext(), "set focus ring value to max", Toast.LENGTH_SHORT).show();
}
});
}

Intent intent = new Intent(getApplication(), TCPService.class);
getApplication().startService(intent);
}

@Override
protected void onResume() {
super.onResume();
}

public static boolean isMultiStreamPlatform() {
if (DJISDKManager.getInstance() == null){
return false;
}
Model model = DJISDKManager.getInstance().getProduct().getModel();
return model != null && (model == Model.INSPIRE_2
|| model == Model.MATRICE_200
|| model == Model.MATRICE_210
|| model == Model.MATRICE_210_RTK
|| model == Model.MATRICE_600
|| model == Model.MATRICE_600_PRO
|| model == Model.A3
|| model == Model.N3);
}

private void initUI() {
primaryVideoFeedView = (VideoFeedView) findViewById(R.id.video_view_primary_video_feed);
primaryVideoFeedView.registerLiveVideo(VideoFeeder.getInstance().getPrimaryVideoFeed(), true);

fpvVideoFeedView = (VideoFeedView) findViewById(R.id.video_view_fpv_video_feed);
fpvVideoFeedView.registerLiveVideo(VideoFeeder.getInstance().getSecondaryVideoFeed(), false);
if (isMultiStreamPlatform()){
fpvVideoFeedView.setVisibility(View.VISIBLE);
}

showUrlInputEdit = (EditText) findViewById(R.id.edit_live_show_url_input);
showUrlInputEdit.setText(liveShowUrl);

startLiveShowBtn = (Button) findViewById(R.id.btn_start_live_show);
enableVideoEncodingBtn = (Button) findViewById(R.id.btn_enable_video_encode);
disableVideoEncodingBtn = (Button) findViewById(R.id.btn_disable_video_encode);
stopLiveShowBtn = (Button) findViewById(R.id.btn_stop_live_show);
soundOnBtn = (Button) findViewById(R.id.btn_sound_on);
soundOffBtn = (Button) findViewById(R.id.btn_sound_off);
isLiveShowOnBtn = (Button) findViewById(R.id.btn_is_live_show_on);
showInfoBtn = (Button) findViewById(R.id.btn_show_info);
showLiveStartTimeBtn = (Button) findViewById(R.id.btn_show_live_start_time);
showCurrentVideoSourceBtn = (Button) findViewById(R.id.btn_show_current_video_source);
changeVideoSourceBtn = (Button) findViewById(R.id.btn_change_video_source);

startLiveShowBtn.setOnClickListener(this);
enableVideoEncodingBtn.setOnClickListener(this);
disableVideoEncodingBtn.setOnClickListener(this);
stopLiveShowBtn.setOnClickListener(this);
soundOnBtn.setOnClickListener(this);
soundOffBtn.setOnClickListener(this);
isLiveShowOnBtn.setOnClickListener(this);
showInfoBtn.setOnClickListener(this);
showLiveStartTimeBtn.setOnClickListener(this);
showCurrentVideoSourceBtn.setOnClickListener(this);
changeVideoSourceBtn.setOnClickListener(this);
}

private void initListener() {
showUrlInputEdit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
liveShowUrl = s.toString();
}

@Override
public void afterTextChanged(Editable s) {

}
});
listener = new LiveStreamManager.OnLiveChangeListener() {
@Override
public void onStatusChanged(int i) {
//Toast.makeText(getApplicationContext(), "status changed : " + i, Toast.LENGTH_SHORT).show();
}
};
}



@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
BaseProduct product = DronifyApplication.getProductInstance();
if (product == null || !product.isConnected()) {
//Toast.makeText(getApplicationContext(), "disconnected", Toast.LENGTH_SHORT).show();
return;
}
if (isLiveStreamManagerOn()){
DJISDKManager.getInstance().getLiveStreamManager().registerListener(listener);
}
}

@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (isLiveStreamManagerOn()){
DJISDKManager.getInstance().getLiveStreamManager().unregisterListener(listener);
}
}

private boolean isLiveStreamManagerOn() {
if (DJISDKManager.getInstance().getLiveStreamManager() == null) {
//Toast.makeText(getApplicationContext(), "no liveStream manager", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start_live_show:
startLiveShow();
break;
case R.id.btn_enable_video_encode:
enableReEncoder();
break;
case R.id.btn_disable_video_encode:
disableReEncoder();
break;
case R.id.btn_stop_live_show:
stopLiveShow();
break;
case R.id.btn_sound_on:
soundOn();
break;
case R.id.btn_sound_off:
soundOff();
break;
case R.id.btn_is_live_show_on:
isLiveShowOn();
break;
case R.id.btn_show_info:
showInfo();
break;
case R.id.btn_show_live_start_time:
showLiveStartTime();
break;
case R.id.btn_show_current_video_source:
showCurrentVideoSource();
break;
case R.id.btn_change_video_source:
changeVideoSource();
break;
default:
break;
}
}



private void enableReEncoder() {
if (!isLiveStreamManagerOn()) {
return;
}
DJISDKManager.getInstance().getLiveStreamManager().setVideoEncodingEnabled(true);
Toast.makeText(getApplicationContext(), "Force Re-Encoder Enabled!", Toast.LENGTH_SHORT).show();
}

private void disableReEncoder() {
if (!isLiveStreamManagerOn()) {
return;
}
DJISDKManager.getInstance().getLiveStreamManager().setVideoEncodingEnabled(false);
Toast.makeText(getApplicationContext(), "Disable Force Re-Encoder!", Toast.LENGTH_SHORT).show();
}


private void soundOn() {
if (!isLiveStreamManagerOn()) {
return;
}
DJISDKManager.getInstance().getLiveStreamManager().setAudioMuted(false);
Toast.makeText(getApplicationContext(), "Sound ON", Toast.LENGTH_SHORT).show();
}

private void soundOff() {
if (!isLiveStreamManagerOn()) {
return;
}
DJISDKManager.getInstance().getLiveStreamManager().setAudioMuted(true);
Toast.makeText(getApplicationContext(), "Sound OFF", Toast.LENGTH_SHORT).show();
}

private void isLiveShowOn() {
if (!isLiveStreamManagerOn()) {
return;
}
Toast.makeText(getApplicationContext(), "Is Live Show On:" + DJISDKManager.getInstance().getLiveStreamManager().isStreaming(), Toast.LENGTH_SHORT).show();
}


private void showLiveStartTime() {
if (!isLiveStreamManagerOn()) {
return;
}
if (!DJISDKManager.getInstance().getLiveStreamManager().isStreaming()){
Toast.makeText(getApplicationContext(), "Please Start Live First", Toast.LENGTH_SHORT).show();
return;
}
long startTime = DJISDKManager.getInstance().getLiveStreamManager().getStartTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String sd = sdf.format(new Date(Long.parseLong(String.valueOf(startTime))));
Toast.makeText(getApplicationContext(), "Live Start Time: " + sd, Toast.LENGTH_SHORT).show();
}

private void changeVideoSource() {
if (!isLiveStreamManagerOn()) {
return;
}
if (!isSupportSecondaryVideo()) {
return;
}
if (DJISDKManager.getInstance().getLiveStreamManager().isStreaming()) {
Toast.makeText(getApplicationContext(), "Before change live source, you should stop live stream!", Toast.LENGTH_SHORT).show();
return;
}
currentVideoSource = (currentVideoSource == LiveStreamManager.LiveStreamVideoSource.Primary) ?
LiveStreamManager.LiveStreamVideoSource.Secoundary :
LiveStreamManager.LiveStreamVideoSource.Primary;
DJISDKManager.getInstance().getLiveStreamManager().setVideoSource(currentVideoSource);
Toast.makeText(getApplicationContext(), "Change Success ! Video Source : " + currentVideoSource.name(), Toast.LENGTH_SHORT).show();
}

private void showCurrentVideoSource(){
Toast.makeText(getApplicationContext(), "Video Source : " + currentVideoSource.name(), Toast.LENGTH_SHORT).show();
}

private boolean isSupportSecondaryVideo(){
if (isMultiStreamPlatform()) {
Toast.makeText(getApplicationContext(), "No secondary video!", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}

private void showInfo() {
StringBuilder sb = new StringBuilder();
sb.append("Video BitRate:").append(DJISDKManager.getInstance().getLiveStreamManager().getLiveVideoBitRate()).append(" kpbs\n");
sb.append("Audio BitRate:").append(DJISDKManager.getInstance().getLiveStreamManager().getLiveAudioBitRate()).append(" kpbs\n");
sb.append("Video FPS:").append(DJISDKManager.getInstance().getLiveStreamManager().getLiveVideoFps()).append("\n");
sb.append("Video Cache size:").append(DJISDKManager.getInstance().getLiveStreamManager().getLiveVideoCacheSize()).append(" frame");
Toast.makeText(getApplicationContext(), sb.toString(), Toast.LENGTH_LONG).show();
}

void startLiveShow() {
Toast.makeText(getApplicationContext(), "start live show: " + isLiveStreamManagerOn(), Toast.LENGTH_SHORT).show();
if (!isLiveStreamManagerOn()) {
Toast.makeText(getApplicationContext(), "1. return", Toast.LENGTH_SHORT).show();
return;
}
if (DJISDKManager.getInstance().getLiveStreamManager().isStreaming()) {
Toast.makeText(getApplicationContext(), "live show already started", Toast.LENGTH_SHORT).show();
return;
}

new Thread() {
@Override
public void run() {
DJISDKManager.getInstance().getLiveStreamManager().setLiveUrl(liveShowUrl);
DJISDKManager.getInstance().getLiveStreamManager().setVideoEncodingEnabled(true);
DJISDKManager.getInstance().getLiveStreamManager().setAudioMuted(false);
final int result = DJISDKManager.getInstance().getLiveStreamManager().startStream();
DJISDKManager.getInstance().getLiveStreamManager().setStartTime();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplication(), "RESULT: " + result, Toast.LENGTH_SHORT).show();
}
});
}
}.start();
}

private void stopLiveShow() {
if (!isLiveStreamManagerOn()) {
return;
}
DJISDKManager.getInstance().getLiveStreamManager().stopStream();
Toast.makeText(getApplicationContext(), "stop live show", Toast.LENGTH_SHORT).show();
}
}

知道为什么吗?我在 Google Pixel 2 和华为 Mate 10 上进行了测试。该示例在这两种设备上都没有问题,我的应用程序有延迟。谢谢!

最佳答案

回答我自己的问题时,我注意到的唯一区别是 SampleCode 要求 4 个权限,而我尝试或复制权限的所有项目始终只有 3 个权限。

所以 list :

< uses-permission android:name="android.permission.RECORD_AUDIO" />

您的运行时权限:

Manifest.permission.RECORD_AUDIO

延迟消失了,一切正常。还是不知道为什么:)

关于java - 使用 DJI Android SDK LiveStreamManager 直播无人机摄像头有很大的延迟。使用 SampleCode 却没有,我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58538465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com