Livestreaming von MobilgerÀten aus ermöglicht es Ihnen, mit Ihrem Publikum zu connecten, unabhÀngig davon, wo Sie sich gerade befinden. Entsprechende Dienste sind sehr beliebt und werden in den verschiedensten Anwendungsbereichen genutzt.
In diesem Artikel werden wir nĂ€her darauf eingehen, wie Sie Ihre eigene Anwendung fĂŒr mobiles Streaming und das Betrachten von Livestreams auf Android erstellen und wie Sie diese in Gcore Streaming-Plattform integrieren können.

Streaming-Protokolle
Streaming-Protokolle werden verwendet, um Video und Audio ĂŒber öffentliche Netzwerke zu ĂŒbertragen. Eines der gĂ€ngigsten Streaming-Protokolle ist RTMP. Es wird von den meisten Streaming-Plattformen unterstĂŒtzt. RTMP ist zuverlĂ€ssig und eignet sich aufgrund der niedrigen Latenzzeit und der wiederholten Ăbertragung von Datenpaketen auf der Grundlage des TCP Protokolls perfekt fĂŒr Livestreaming.
Um Content auf die GerĂ€te von Nutzern zu bringen und ihn dort abzuspielen, bieten Streaming-Plattformen die beliebten und skalierbaren Broadcast-Formate HLS und DASH an. DarĂŒber hinaus sind Android-GerĂ€te von Haus aus mit einem MediaPlayer ausgestattet, der die HLS Wiedergabe unterstĂŒtzt. Aus diesem Grund werden wir uns schwerpunktmĂ€Ăig mit diesem Protokoll befassen.
AuswÀhlen einer Bibliothek zum Erstellen eines RTMP Streams
Es gibt nur wenige Open-Source-Lösungen fĂŒr RTMP Streaming ĂŒber Android-GerĂ€te, und noch weniger wirklich funktionelle Optionen. Sehen wir uns einige von ihnen genauer an.
1. rtmp-rtsp-stream-client-java
Vorteile:
- Neue, regelmĂ€Ăig aktualisierte Bibliothek
- MindestunterstĂŒtzung fĂŒr API 16
- UnterstĂŒtzung fĂŒr die APIs Camera und Camera2
- Kamerawechsel wÀhrend des Streamens
- Adaptive Bitrate
- Aktivierung/Deaktivierung von Audio und Video wÀhrend des Streamens
- Möglichkeit zum Konfigurieren von Broadcasting-Parametern
- Installation von OpenGL Filtern, Bildern, GIFs oder Text in Echtzeit
- Einfach zu bedienen: alles funktioniert standardmĂ€Ăig, ohne zusĂ€tzliche Anpassungen
- VerfĂŒgbarkeit von Dokumentation und Anleitungen fĂŒr die Bibliothek auf GitHub
- Unkompliziertes Importieren von Bibliotheken ĂŒber Gradle
Nachteile:
- Keine Pausefunktion fĂŒr einen Broadcast-Stream verfĂŒgbar
2. HaishinKit
Vorteile:
- Stabile Updates
- UnterstĂŒtzt RTMP Wiedergabe
- Verwendet die aktuelle Camera2-API
- UnterstĂŒtzt Kamerawechsel wĂ€hrend des Streamens
- Erlaubt das Konfigurieren von Broadcasting-Parametern
Nachteile:
- Keine Option fĂŒr eine adaptive Bitrate
- Keine Pausefunktion fĂŒr einen Broadcast-Stream verfĂŒgbar
3. LiveVideoBroadcaster
Vorteile:
- MindestunterstĂŒtzung fĂŒr API 28
- Kamerawechsel wÀhrend des Streamens
- Adaptive Stream-QualitÀt (Framerate und Bitrate)
- Aktivierung/Deaktivierung von Audio wÀhrend des Streamens
Nachteile:
- Nicht mehr aktuell: letztes Update am 28. Juli 2020
- Verwendet veraltete Camera-API
- Kein Importieren von Bibliotheken ĂŒber Gradle möglich
- Sehr viel komplexer als rtmp-rtsp-stream-client-java
- Von der Bibliothek gesendete Frames enthalten Fehler (DC, AC, MV)
Zusammenfassend lĂ€sst sich sagen, dass rtmp-rtsp-stream-client-java unter allen drei Optionen die meisten Vorteile und die wenigsten Nachteile aufweist. Aus diesem Grund halten wir diese Bibliothek fĂŒr die am besten geeignete Lösung.
Streaming-Implementierung ĂŒber das RTMP Protokoll von einem Android-Smartphone
Die Bibliothek rtmp-rtsp-stream-client-java bietet zwei Arten von Objekten fĂŒr das Streaming â RtmpCamera1 und RtmpCamera2. Ersteres verwendet die Camera-API, um den Stream von Ihrer Smartphone-Kamera zu erfassen, wĂ€hrend Letzteres die Camera2-API verwendet.
Wir empfehlen die Verwendung von RtmpCamera2, da die Camera-API seit Android API Level 21 veraltet ist. In unserem Beispiel wird die aktuellste RtmpCamera2-Version verwendet.
Wir werden uns nun Schritt fĂŒr Schritt ansehen, wie die Bibliothek rtmp-rtsp-stream-client-java fĂŒr mobiles Streaming verwendet wird. Doch zunĂ€chst ein kurzer Ăberblick ĂŒber ihre Funktionsweise.
- Wenn die Methodeaufgerufen wird, wird das Bild der Kamera erfasst.
- Die erfasste Kamerasitzung wird an den OpenGlView-Eingang gesendet, wo sie dem Benutzer angezeigt wird.
- Wenn die Methodeaufgerufen wird, wird eine Verbindung zum Remote-Server hergestellt.
- Die von der Kamera erfasste Sitzung wird ĂŒber das RTMP Protokoll an die festgelegte rtmpUrl ĂŒbertragen.
Schauen wir uns nun Schritt fĂŒr Schritt an, wie man mobiles Online-Streaming einrichtet.
1. Init
Um die Bibliothek rtmp-rtsp-stream-client-java in Ihrem Projekt zu verwenden, mĂŒssen Sie AbhĂ€ngigkeiten zu build.gradle hinzufĂŒgen:
allprojects { repositories { maven { url âhttps://jitpack.ioâ } }}dependencies { implementation âcom.github.pedroSG94.rtmp-rtsp-stream-client- java:rtplibrary:2.1.7â}
Aktuelle Version der Bibliothek
2. Berechtigungen
Geben Sie die erforderlichen Berechtigungen in der Datei AndroidManifest.xml an:
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.RECORD_AUDIO"/>
3. Anzeigen des Kamera-Streams
Wenn Sie mit einer Smartphone-Kamera streamen, mĂŒssen Sie sehen, was der Stream zeigt. Zu diesem Zweck wird in einer entsprechenden Ansicht der Kamerastream auf dem Bildschirm angezeigt. Android verwendet SurfaceView oder TextureView. Die verwendete Bibliothek verfĂŒgt auch ĂŒber eine eigene OpenGlView, die von SurfaceView abstammt.
Mit RtmpCamera1 können Sie jede dieser Ansichten verwenden, wohingegen mit RtmpCamera2 nur OpenGlView verfĂŒgbar ist. Aber von diesen Ansichten ermöglicht Ihnen nur OpenGlView, verschiedene Filter, Bilder, GIFs oder Text wĂ€hrend des Streamens zu verwenden.
FĂŒgen Sie OpenGlView zu âLayout Activityâ oder âFragmentâ hinzu, um den Kamerastream zu sehen:
<com.pedro.rtplibrary.view.OpenGlView android:id="@+id/openGlView" android:layout_width="match_parent" android:layout_height="match_parent" android:keepScreenOn="true" android:visibility="gone" app:keepAspectRatio="true" app:aspectRatioMode="adjust"/>

4. Vorbereitungen fĂŒr das Streamen
Um das Objekt RtmpCamera2 zu initialisieren, benötigen Sie das Objekt OpenGlView und die Schnittstellenimplementierung ConnectCheckerRtmp:
private val connectCheckerRtmp = object : ConnectCheckerRtmp { override fun onAuthErrorRtmp() { _toastMessageId.postValue(R.string.auth_error) } override fun onAuthSuccessRtmp() { _toastMessageId.postValue(R.string.auth_success) } override fun onConnectionFailedRtmp(reason: String) { _toastMessageId.postValue(R.string.connection_failed) stopBroadcast() } override fun onConnectionStartedRtmp(rtmpUrl: String) {} override fun onConnectionSuccessRtmp() { _toastMessageId.postValue(R.string.connection_success) _streamState.postValue(StreamState.PLAY) } override fun onDisconnectRtmp() { _toastMessageId.postValue(R.string.disconnected) _streamState.postValue(StreamState.STOP) } override fun onNewBitrateRtmp(bitrate: Long) {}}
Um die adaptive Bitrate zu verwenden, mĂŒssen Sie einige ErgĂ€nzungen an der Implementierung dieser Schnittstelle vornehmen:
//... private lateinit var bitrateAdapter: BitrateAdapter override fun onConnectionSuccessRtmp() { bitrateAdapter = BitrateAdapter { bitrate -> rtmpCamera2?.setVideoBitrateOnFly(bitrate) }.apply { setMaxBitrate(StreamParameters.maxBitrate) } _toastMessageId.postValue(R.string.connection_success) _currentBitrate.postValue(rtmpCamera2?.bitrate)_streamState.postValue(StreamState.PLAY) } //... override fun onNewBitrateRtmp(bitrate: Long) { bitrateAdapter.adaptBitrate(bitrate) _currentBitrate.postValue(bitrate.toInt()) disableStreamingAfterTimeOut() }
FĂŒgen Sie einen Callback zum Objekt OpenGlView hinzu. Die Callback-Methoden werden dazu verwendet, die Kameravorschau zu starten und zu beenden:
private val surfaceHolderCallback = object : SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) { rtmpCamera2?.startPreview( StreamParameters.resolution.width, StreamParameters.resolution.height ) } override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {} override fun surfaceDestroyed(holder: SurfaceHolder) { rtmpCamera2?.stopPreview() } }binding.openGlView.holder.addCallback(surfaceHolderCallback)
Erstellen Sie das Objekt RtmpCamera2, das fĂŒr das Streaming verwendet werden soll:
rtmpCamera2 = RtmpCamera2(openGlView, connectCheckerRtmp)
5. Starten und Beenden von Livestreams
Legen Sie die Video- und Audioparameter fest, und starten Sie den Livestream.
Livestream mit Standardparametern:
fun startBroadcast(rtmpUrl: String) { rtmpCamera2?.let { if (!it.isStreaming) { if (it.prepareAudio() && it.prepareVideo()) { _streamState.value = StreamState.PLAY it.startStream(rtmpU } else { _streamState.value = StreamState.STOP_toastMessageId.value = R.string.error_preparing_stream } } }}
Livestream mit benutzerdefinierten Parametern:
fun startBroadcast(rtmpUrl: String) { val audioIsReady = rtmpCamera2.prepareAudio( StreamParameters.audioBitrate, StreamParameters.sampleRate, StreamParameters.isStereo, StreamParameters.echoCanceler, StreamParameters.noiseSuppressor ) val videoIsReady = rtmpCamera2.prepareVideo( StreamParameters.resolution.width, StreamParameters.resolution.height, StreamParameters.fps, StreamParameters.startBitrate, StreamParameters.iFrameIntervalInSeconds, CameraHelper.getCameraOrientation(getApplication()) ) rtmpCamera2?.let { if (!it.isStreaming) { if (audioIsReady && videoIsReady) { _streamState.value = StreamState.PLAY it.startStream(rtmpU } else { _streamState.value = StreamState.STOP _toastMessageId.value = R.string.error_preparing_stream } } }}
Den Stream beenden:
fun stopBroadcast() { rtmpCamera2?.let { if (it.isStreaming) { _streamState.value = StreamState.STOP it.stopStream() } }}
Integration mit Gcore Streaming-Plattform
Erstellen eines Kontos bei Gcore
Um die Streaming-Plattform in das Projekt zu integrieren, mĂŒssen Sie mit Ihrer E-Mail und Ihrem Kennwort ein kostenfreies Konto bei Gcore erstellen.
Aktivieren Sie den Dienst, indem Sie Free Live oder einen anderen geeigneten Tarif wÀhlen.
FĂŒr die Interaktion mit Gcore Streaming-Plattform werden wir die Gcore-API verwenden. Wir werden Anfragen unter Verwendung von Retrofit in Verbindung mit RxJava ausfĂŒhren. Sie können aber auch jede andere Methode zur Ăbermittlung von HTTP Anfragen verwenden, wenn Sie möchten.
Autorisierung
Loggen Sie sich ein, um mit der API zu arbeiten. Verwenden Sie die E-Mail und das Kennwort, die Sie bei der Registrierung eingegeben haben, um den Access Token zu erhalten, den Sie fĂŒr weitere Anfragen benötigen.
class AuthRequestBody( @SerializedName("username") val eMail: String, @SerializedName("password") val password: String,@SerializedName("one_time_password") val oneTimePassword: String = "authenticator passcode")interface AuthApi { @POST("./auth/jwt/login") fun performLogin(@Body body: AuthRequestBody): Single<AuthResponse>}private fun auth(eMail: String, password: String) { val requestBody = AuthRequestBody(eMail = eMail, password = password) compositeDisposable.add( (requireActivity().application as GCoreApp).authApi .performLogin(requestBody) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .auth(requireActivity(), requestBody) .subscribe({ authResponse ->showToast(R.string.logged_success) saveAuthData(requestBody, authResponse) routeToStreams() }, { showToast(R.string.logged_fail) }) )}
Die PUSH URL abrufen
Es gibt zwei Möglichkeiten, die URL zum Senden des RTMP Streams abzurufen:
Methode 1. Senden Sie die Anfrage Get all live streams, um alle Livestreams abzurufen. Als Antwort erhalten Sie Daten ĂŒber alle in Ihrem Konto erstellten Streams.
Ein Beispiel fĂŒr das Senden einer Anfrage:
interface StreamsApi { /** * @param page integer; Query parameter. Use it to list the paginated content * @param with_broadcasts integer; Query parameter. * Set to 1 to get details of the broadcasts associated with the stream */ @GET("./vp/api/streams") fun getStreams( @Header("Authorization") accessToken: String, @Query("page") page: Int, @Query("with_broadcasts") withBroadcasts: Int = 1 ): Single<List<StreamItemResponse>> //...}private fun loadStreamItems(page: Int = 1) { val accessToken = getAccessToken() var currentPage = page if (currentPage == 1) { streamItems.clear() } compositeDisposable.add( (requireActivity().application as GCoreApp).streamsApi .getStreams("Bearer $accessToken", page = currentPage) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ if (it.isNotEmpty()) { it.forEach { streamItemResponse -> streamItems.add(StreamItemModel.getInstance(streamItemResponse)) } loadStreamItems(page = ++currentPage) } else { updateDataInAdapter() } }, { it.printStackTrace() }) )}
Methode 2. Senden Sie die Anfrage Get live stream, um einen bestimmten Livestream abzurufen. Als Antwort erhalten Sie nur Daten ĂŒber den angegebenen Stream, sofern dieser existiert.
Ein Beispiel fĂŒr das Senden einer Anfrage:
interface StreamsApi { //... @GET("/vp/api/streams/{stream_id}") fun getStreamDetailed( @Header("Authorization") accessToken: String, @Path("stream_id") streamId: Int ): Single<StreamDetailedResponse> //...}private fun getStreamDetailedInfo(streamId: Int) { val accessToken = getAccessToken() compositeDisposable.add( (requireActivity().application as GCoreApp).streamsApi .getStreamDetailed("Bearer $accessToken", streamId) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ streamDetailedInfo -> //... }, { it.printStackTrace() }) )}
Die Antworten auf diese Anfragen enthalten eine push_url, die als URL fĂŒr das Senden des RTMP Streams verwendet wird. Sobald der Stream beginnt, wird die Ăbertragung automatisch gestartet. WĂ€hlen Sie den gewĂŒnschten Stream in Ihrem persönlichen Konto aus. Sie können die Vorschau verwenden, bevor Sie den Stream auf Ihrer Website oder in Ihrem Player bereitstellen.
Wiedergabe eines aktiven Streams
Mit Gcore Streaming-Plattform können Sie Streams auf Ressourcen von Drittanbietern in verschiedenen Formaten, einschlieĂlich HLS, ĂŒbertragen.
In unserem Beispiel berĂŒcksichtigen wir kein simultanes Streamen und Wiedergeben auf einem GerĂ€t. Stattdessen sollte das Streamen von einem anderen GerĂ€t aus gestartet werden.
Um den aktiven Stream wiederzugeben, verwenden Sie den standardmĂ€Ăigen Android MediaPlayer. Wenn Sie mehr Kontrolle ĂŒber den Stream und die Anpassungsmöglichkeiten des Players haben möchten, empfehlen wir ExoPlayer.
On-Screen-Display
Um den Videostream auf dem Smartphone-Bildschirm anzuzeigen, ist VideoView erforderlich. Es sollte dort zu âLayout Activityâ oder âFragmentâ hinzugefĂŒgt werden, wo Sie den Stream abspielen möchten:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@color/black" android:id="@+id/streamPlayer" tools:context=".screens.StreamPlayerFragment"> <VideoView android:id="@+id/videoView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center"/> ...</FrameLayout>
Wiedergabe starten
Vor der Wiedergabe sollte die hls_playlist_url des aktiven Streams in den Player eingebettet werden, wĂ€hrend dieser initialisiert wird. Die hls_playlist_url wird in der Antwort auf die oben erwĂ€hnte Anfrage âGet livestreamâ zurĂŒckgegeben.
Initialisierung des Players:
private fun initializePlayer(streamUri: String) { val videoView = binding.videoView videoView.setVideoURI(Uri.parse(streamUri)) val mediaController = MediaController(videoView.context) mediaController.setMediaPlayer(videoView) videoView.setMediaController(mediaController) videoView.setOnPreparedListener { binding.progressBar.visibility = View.GONE videoView.start() } videoView.setonerrorListener(mediaPlayeronerrorListener)}
Sobald die Initialisierung abgeschlossen ist, können Sie die Wiedergabe durch Aufruf der Methode videoView.start() starten.
Starten des Players:
private fun releasePlayer() { binding.videoView.stopPlayback()}
Zusammenfassung
Anhand unserer Beispiele ist das Einrichten eines Livestreams in einer Android-Anwendung denkbar einfach und nimmt nicht viel Zeit in Anspruch. Alles, was Sie dazu benötigen, ist die Open-Source-Bibliothek rtmp-rtsp-stream-client-java und unsere Streaming-Plattform.
Gcore Streaming-API
Jeglichen im Artikel erwÀhnten Code finden Sie auf GitHub.
Ăhnliche Artikel
Melden Sie sich fĂŒr unseren Newsletter an
Erhalten Sie die neuesten Branchentrends, exklusive Einblicke und Gcore-Updates direkt in Ihren Posteingang.