Playing a UDP Multicast Stream in Android using Media3
create a UDP multicast stream in Android using androidx.media3…
Playing a UDP Multicast Stream in Android using Media3
In this guide, we will demonstrate how to create a UDP multicast stream in Android using androidx.media3. https://developer.android.com/jetpack/androidx/releases/media3
File Structure
- MainActivity.kt: Handles player binding and UI interactions.
- build.gradle.kts: Includes dependencies and setup for the project.
- MulticastController.kt: Contains the multicast socket code.
- TunerDataSource.kt: Reads data from
MulticastControllerand feeds it to the player. - activity_main.xml: Defines the layout for the player.

MainActivity.kt
package com.example.udpstreaming
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private var player: ExoPlayer? = null
private lateinit var playerView: PlayerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
playerView = findViewById(R.id.player_view)
val multicastTuner = MulticastController("239.0.0.12", 1234)
// replace with your multicast ip and port
lifecycleScope.launch {
try {
initializePlayer(multicastTuner)
} catch (e: Exception) {
Log.e("MainActivity", "Error initializing player: ${e.message}", e)
}
}
}
private fun initializePlayer(multicastTuner: MulticastController) {
player = ExoPlayer.Builder(this).build().apply {
val tunerDataSource = TunerDataSource(multicastTuner)
val mediaSource = tunerDataSource.createMediaSource()
setMediaSource(mediaSource)
prepare()
playWhenReady = true
playerView.player = this
}
}
override fun onDestroy() {
super.onDestroy()
player?.release()
}
}
build.gradle.kts
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
compileSdk = 33
defaultConfig {
applicationId = "com.example.udpstreaming"
minSdk = 21
targetSdk = 33
versionCode = 1
versionName = "1.0"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
val media3_version = "1.5.0"
// other dependencies
implementation("androidx.media3:media3-exoplayer:$media3_version")
implementation("androidx.media3:media3-ui:$media3_version")
}
MulticastController.kt
This file contains the implementation for the multicast socket:
package com.example.udpstreaming
import java.io.IOException
import java.net.DatagramPacket
import java.net.InetAddress
import java.net.MulticastSocket
class MulticastController(private val host: String, private val port: Int) {
private lateinit var socket: MulticastSocket
fun start() {
try {
val multicastGroup = InetAddress.getByName(host)
socket = MulticastSocket(port).apply {
reuseAddress = true
joinGroup(multicastGroup)
soTimeout = 5000
}
} catch (e: Exception) {
throw IOException("Failed to initialize multicast socket: ${e.message}")
}
}
fun stop() {
if (::socket.isInitialized && !socket.isClosed) {
socket.leaveGroup(InetAddress.getByName(host))
socket.close()
}
}
fun fetchData(buffer: ByteArray): Int {
val packet = DatagramPacket(buffer, buffer.size)
socket.receive(packet)
return packet.length
}
}
TunerDataSource.kt
This file connects the MulticastController to the player:
package com.example.udpstreaming
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import androidx.media3.datasource.DataSource
import androidx.media3.datasource.DataSpec
import java.io.IOException
class TunerDataSource(private val tuner: MulticastController) : DataSource {
private var opened = false
override fun open(dataSpec: DataSpec): Long {
tuner.start()
opened = true
return DataSpec.LENGTH_UNSET.toLong()
}
override fun read(buffer: ByteArray, offset: Int, length: Int): Int {
if (!opened) throw IOException("DataSource not opened.")
return tuner.fetchData(buffer.copyOfRange(offset, offset + length))
}
override fun close() {
if (opened) tuner.stop()
opened = false
}
override fun getUri() = null
fun createMediaSource(): ProgressiveMediaSource {
return ProgressiveMediaSource.Factory { this }.createMediaSource(null)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:keepScreenOn="true" />
</RelativeLayout>
Key Interactions:
- MainActivity → Sets up ExoPlayer and UI interactions.
- MulticastController → Manages the UDP multicast socket, receiving and handling data.
- TunerDataSource → Acts as a bridge between the ExoPlayer and the multicast data, feeding the stream data to ExoPlayer.
- ExoPlayer → Decodes and plays the media content on the UI.
Final Steps:
- Network Permissions: Make sure you have the necessary permissions to use the network in your
AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Creating a UDP Stream using VLC or FFmpeg
To create a UDP multicast stream, you can use tools like VLC or FFmpeg. These tools allow you to broadcast media over a network using UDP multicast.
Using VLC:
- Open VLC and go to Media → Stream.
- In the File tab, select the media file you want to stream.
- Click Stream and then choose UDP (multicast) as the destination.
- Set the Address to your multicast IP (e.g.,
239.0.0.12) and the Port to the desired value (e.g.,1234). - Click Stream to start broadcasting.
Using FFmpeg:
To create a UDP multicast stream with FFmpeg, use the following command in the terminal:
ffmpeg -i input_video.mp4 -c:v libx264 -f mpegts udp://239.0.0.12:1234?ttl=64
This command tells FFmpeg to read the input_video.mp4 file, encode it using the libx264 codec, and stream it as an MPEG-TS packet over UDP to the multicast IP 239.0.0.12 on port 1234. The ttl=64 option sets the Time-to-Live for the multicast packets.
Don’t forget to save this article for later reading! A clap 👏 would really motivate me to keep going.
If you’d like the complete working code on GitHub, feel free to leave a comment.
메타데이터
- post_id
- d13ca69a42ef
- slug
- playing-a-udp-multicast-stream-in-android-using-media3-d13ca69a42ef
- url
- https://medium.com/@amitdogra70512/playing-a-udp-multicast-stream-in-android-using-media3-d13ca69a42ef
- canonical_url
- https://medium.com/@amitdogra70512/playing-a-udp-multicast-stream-in-android-using-media3-d13ca69a42ef
- author_url
- https://medium.com/@amitdogra70512
- status
- ok
- fetched_at
- 2026-08-11 15:23:59