Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

13.12. ExoPlayer

13.12.1. Opus

13.12.1.1. 文件

		
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.ui.PlayerView

class OpusPlayerActivity : AppCompatActivity() {
    private lateinit var exoPlayer: ExoPlayer
    private lateinit var playerView: PlayerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_opus_player)
        
        playerView = findViewById(R.id.player_view)
        
        // 初始化 ExoPlayer
        exoPlayer = ExoPlayer.Builder(this).build()
        playerView.player = exoPlayer
        
        // 准备 Opus 音频(本地文件或网络 URL)
        val mediaItem = MediaItem.fromUri(Uri.parse("asset:///audio.opus"))
        val dataSourceFactory = DefaultDataSource.Factory(this)
        val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(mediaItem)
        
        // 准备并播放
        exoPlayer.setMediaSource(mediaSource)
        exoPlayer.prepare()
        exoPlayer.playWhenReady = true
    }

    override fun onDestroy() {
        super.onDestroy()
        exoPlayer.release() // 释放资源
    }
}		
		
				

13.12.1.2. 音频流

				
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.ui.PlayerView

class OpusStreamPlayerActivity : AppCompatActivity() {
    private lateinit var exoPlayer: ExoPlayer
    private lateinit var playerView: PlayerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_opus_stream)

        // 初始化播放器和UI
        playerView = findViewById(R.id.player_view)
        exoPlayer = ExoPlayer.Builder(this).build()
        playerView.player = exoPlayer

        // 1. 播放网络 Opus 流(例如:http://example.com/stream.opus)
        val streamUrl = "http://example.com/stream.opus"
        val mediaItem = MediaItem.fromUri(Uri.parse(streamUrl))

        // 2. 配置数据源工厂(支持网络和本地流)
        val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(this)

        // 3. 创建媒体源(渐进式流,适合音频流)
        val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(mediaItem)

        // 4. 准备并播放
        exoPlayer.setMediaSource(mediaSource)
        exoPlayer.prepare()
        exoPlayer.playWhenReady = true // 自动播放
    }

    override fun onDestroy() {
        super.onDestroy()
        // 释放资源,避免内存泄漏
        exoPlayer.release()
    }
}				
				
				

13.12.1.3. 字节流

				
import com.google.android.exoplayer2.upstream.ByteArrayDataSource
import com.google.android.exoplayer2.upstream.DataSource

// 假设 opusBytes 是内存中的 Opus 音频字节数组
val opusBytes: ByteArray = ... 

// 创建内存数据源
val byteArrayDataSource = ByteArrayDataSource(opusBytes)
val dataSourceFactory = DataSource.Factory { byteArrayDataSource }

// 后续步骤同方案1:创建媒体源并播放
val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
    .createMediaSource(MediaItem.fromUri("bytes://opus")) // 自定义URI标识
exoPlayer.setMediaSource(mediaSource)