In order to stream video from an SDL app, we only need to manage a few things. For the most part, the library will handle the majority of logic needed to perform video streaming.
The SdlRemoteDisplay
base class provides the easiest way to start streaming using SDL. The SdlRemoteDisplay
is extended from Android's Presentation
class with modifications to work with other aspects of the SDL Android library.
It is recommended that you extend this as a local class within the service that has the SdlManager
instance.
Extending this class gives developers a familiar, native experience to handling layouts and events on screen.
public static class MyDisplay extends SdlRemoteDisplay{ public MyDisplay(Context context, Display display) { super(context, display); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.stream); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.i(TAG, "Button Clicked"); } }); } }
If you are obfuscating the code in your app, make sure to exclude your class that extends SdlRemoteDisplay
. For more information on how to do that, you can check Proguard Guidelines.
The VideoStreamingManager
can be used to start streaming video after the SdlManager
has successfully been started. This is performed by calling the method startRemoteDisplayStream(Context context, final Class<? extends SdlRemoteDisplay> remoteDisplay, final VideoStreamingParameters parameters, final boolean encrypted)
.
public static class MyDisplay extends SdlRemoteDisplay { public MyDisplay(Context context, Display display) { super(context, display); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.stream); String videoUri = "android.resource://" + context.getPackageName() + "/" + R.raw.sdl; VideoView videoView = findViewById(R.id.videoView); videoView.setVideoURI(Uri.parse(videoUri)); videoView.start(); } }
if (sdlManager.getVideoStreamManager() != null) { sdlManager.getVideoStreamManager().start(new CompletionListener() { @Override public void onComplete(boolean success) { if (success) { sdlManager.getVideoStreamManager().startRemoteDisplayStream(getApplicationContext(), MyDisplay.class, null, false); } else { Log.e(TAG, "Failed to start video streaming manager"); } } }); }
When the HMIStatus
is back to HMI_NONE
it is time to stop the stream. This is accomplished through a method stopStreaming()
.
Map<FunctionID, OnRPCNotificationListener> onRPCNotificationListenerMap = new HashMap<>(); onRPCNotificationListenerMap.put(FunctionID.ON_HMI_STATUS, new OnRPCNotificationListener() { @Override public void onNotified(RPCNotification notification) { OnHMIStatus status = (OnHMIStatus) notification; if (status != null && status.getHmiLevel() == HMILevel.HMI_NONE) { //Stop the stream if (sdlManager.getVideoStreamManager() != null && sdlManager.getVideoStreamManager().isStreaming()) { sdlManager.getVideoStreamManager().stopStreaming(); } } } }); builder.setRPCNotificationListeners(onRPCNotificationListenerMap);