Skip to content

Instantly share code, notes, and snippets.

@niusounds
Created December 6, 2017 07:06
Show Gist options
  • Save niusounds/32550bd4f71087f64bc8afb4253c680b to your computer and use it in GitHub Desktop.
Save niusounds/32550bd4f71087f64bc8afb4253c680b to your computer and use it in GitHub Desktop.
Player interface abstracts MediaPlayer and ExoPlayer.
import android.content.Context
import android.graphics.SurfaceTexture
import android.net.Uri
import android.view.Surface
interface IPlayer {
/**
* コンテンツの全体時間を取得する。単位はミリ秒。
*/
val duration: Long
/**
* 現在の再生時間を取得する。単位はミリ秒。
*/
var currentPosition: Long
/**
* 現在再生中かどうかを取得する。
*/
val isPlaying: Boolean
/**
* 音量
*/
var volume: Float
/**
* 再生完了時のコールバック
*/
var onCompletion: (() -> Unit)?
/**
* 一時停止する。
*/
fun pause()
/**
* 再生を開始する。
*/
fun start()
/**
* 停止する。
*/
fun stop()
/**
* 読み込む。
*/
fun load(uri: Uri)
/**
* リソースを解放する。
*/
fun release()
/**
* 出力先を指定する。
*/
fun setOutput(surfaceTexture: SurfaceTexture)
/**
* 出力先を指定する。
*/
fun setOutput(surface: Surface)
}
class MediaPlayerImpl(
private val context: Context,
private val mp: MediaPlayer) : IPlayer {
private var surface: Surface? = null
override val duration: Long
get() = mp.duration.toLong()
override var currentPosition: Long
set(value) = mp.seekTo(value.toInt())
get() = mp.currentPosition.toLong()
override val isPlaying: Boolean
get() = mp.isPlaying
override var volume: Float = 1.0f
set(value) {
field = value
mp.setVolume(value, value)
}
override var onCompletion: (() -> Unit)? = null
set(value) {
field = value
if (value != null) {
mp.setOnCompletionListener { value() }
} else {
mp.setOnCompletionListener(null)
}
}
override fun pause() = mp.pause()
override fun start() = mp.start()
override fun stop() = mp.stop()
override fun load(uri: Uri) {
mp.reset()
mp.setDataSource(context, uri)
mp.prepare()
}
override fun release() {
surface?.release()
mp.release()
}
override fun setOutput(surfaceTexture: SurfaceTexture) {
surface?.release()
surface = Surface(surfaceTexture)
mp.setSurface(surface)
}
override fun setOutput(surface: Surface) {
this.surface?.release()
this.surface = surface
mp.setSurface(surface)
}
}
class ExoPlayerImpl(
private val context: Context,
private val exoPlayer: SimpleExoPlayer) : IPlayer, Player.EventListener {
private val userAgent = Util.getUserAgent(context, context.applicationInfo.name)
private var surface: Surface? = null
override val duration: Long
get() = exoPlayer.duration
override var currentPosition: Long
set(value) = exoPlayer.seekTo(value)
get() = exoPlayer.currentPosition
override val isPlaying: Boolean
get() = exoPlayer.playWhenReady
override var volume: Float
get() = exoPlayer.volume
set(value) {
exoPlayer.volume = value
}
override var onCompletion: (() -> Unit)? = null
set(value) {
field = value
if (value != null) {
exoPlayer.addListener(this)
} else {
exoPlayer.removeListener(this)
}
}
override fun pause() {
exoPlayer.playWhenReady = false
}
override fun start() {
exoPlayer.playWhenReady = true
}
override fun stop() = exoPlayer.stop()
override fun load(uri: Uri) {
val dataSourceFactory = DefaultDataSourceFactory(context, userAgent)
val extractorsFactory = DefaultExtractorsFactory()
val mediaSource = ExtractorMediaSource(uri, dataSourceFactory, extractorsFactory, null, null)
exoPlayer.prepare(mediaSource)
}
override fun release() {
surface?.release()
exoPlayer.release()
}
override fun setOutput(surfaceTexture: SurfaceTexture) {
surface?.release()
surface = Surface(surfaceTexture)
exoPlayer.setVideoSurface(surface)
}
override fun setOutput(surface: Surface) {
this.surface?.release()
this.surface = surface
exoPlayer.setVideoSurface(surface)
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
when (playbackState) {
Player.STATE_ENDED -> onCompletion?.invoke()
}
}
override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {}
override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {}
override fun onPlayerError(error: ExoPlaybackException?) {}
override fun onLoadingChanged(isLoading: Boolean) {}
override fun onPositionDiscontinuity() {}
override fun onRepeatModeChanged(repeatMode: Int) {}
override fun onTimelineChanged(timeline: Timeline?, manifest: Any?) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment