Skip to content

Commit

Permalink
add a new handler for dealing download mp3 from remote server.
Browse files Browse the repository at this point in the history
  • Loading branch information
weiancheng committed Feb 21, 2018
1 parent d5cbe4d commit 87867b6
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class MainActivity:AppCompatActivity() {
onPlayerStateChanged = { state ->
Log.i("MainActivity", "onPlayerStateChanged: $state")
}

onDownloadTrack = { isSuccess ->
Log.i("MainActivity", "onDownloadTrack: $isSuccess")
}
}

override fun onCreate(savedInstanceState:Bundle?) {
Expand All @@ -51,6 +55,12 @@ class MainActivity:AppCompatActivity() {
val play = findViewById<Button>(R.id.btn_play) as Button
play.setOnClickListener { view ->
player.play(url)
if (player.writeToFile(url, local)) {
Log.i("Weian", "play button, url is valid")
} else {
Log.i("Weian", "play button, url is not valid")
}
player.seekTo(220)
}

val stop = findViewById<Button>(R.id.btn_stop) as Button
Expand Down
5 changes: 4 additions & 1 deletion mediaplayerwithexoplayer2/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="weian.cheng.mediaplayerwithexoplayer"/>
package="weian.cheng.mediaplayerwithexoplayer">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package weian.cheng.mediaplayerwithexoplayer

import android.util.Log
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL

class DownloadHandler(private val url: String, filePath: String, private val eventListener: ExoPlayerEventListener.PlayerEventListener? = null) : Thread() {
private val tag = "DownloadHandler"
private val bufferSize = 2048
private val tempTrackPath = "/storage/emulated/0/Download/temp_track.mp3"
private var totalSize: Int = -1
private var path: String = ""
private var file: File? = null
private var listener: ExoPlayerEventListener.PlayerEventListener? = null

init {
when (filePath.isEmpty()) {
true -> path = tempTrackPath
false -> path = filePath
}
listener = eventListener
}

override fun run() {
super.run()
Runnable {
if (!isRemoteAvailable()) {
listener?.onDownloadTrack(false)
Thread.currentThread().interrupt()
}

if (!createFile()) {
listener?.onDownloadTrack(false)
Thread.currentThread().interrupt()
}

if (!downloadFile()) {
listener?.onDownloadTrack(false)
Thread.currentThread().interrupt()
} else {
listener?.onDownloadTrack(true)
}

}.run()
}

private fun isRemoteAvailable(): Boolean {
var result = false
Log.i(tag, "url is $url")
val httpURLConnection = URL(url).openConnection() as HttpURLConnection
HttpURLConnection.setFollowRedirects(false)
httpURLConnection.connect()
httpURLConnection.requestMethod = "GET"
if (httpURLConnection.responseCode == HttpURLConnection.HTTP_OK)
result = true

totalSize = httpURLConnection.contentLength
httpURLConnection.disconnect()
return result
}

private fun createFile(): Boolean {
file = File(path)
file?.takeIf { it.exists() }.let {
it?.createNewFile()
}

return true
}

private fun downloadFile(): Boolean {
val fileOutputStream = FileOutputStream(file)
val inputStream = BufferedInputStream(URL(url).openStream())

var downloadSize = 0

val buffer = ByteArray(bufferSize)
var bufferLength: Int
while (true) {
bufferLength = inputStream.read(buffer)
if (bufferLength <= 0)
break
fileOutputStream.write(buffer, 0, bufferLength)
downloadSize += bufferLength
}

fileOutputStream.flush()
fileOutputStream.close()
inputStream.close()
if (downloadSize != totalSize) {
Log.e(tag, "file was not complete")
return false
}
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ class ExoPlayerEventListener {
fun onBufferPercentage(percent: Int)
fun onCurrentTime(second: Int)
fun onPlayerStateChanged(state: MusicPlayerState)
fun onDownloadTrack(isSuccess: Boolean)
}

class PlayerEventListenerFunc {
var onDurationChanged: ((duration: Int) -> Unit)? = null
var onBufferPercentage: ((percent: Int) -> Unit)? = null
var onCurrentTime: ((second: Int) -> Unit)? = null
var onPlayerStateChanged: ((state: MusicPlayerState) -> Unit)? = null
var onDownloadTrack: ((isSuccess: Boolean) -> Int)? = null
}

class PlayerEventListener(func: PlayerEventListenerFunc.() -> Unit): IEventListener {
Expand All @@ -40,5 +42,9 @@ class ExoPlayerEventListener {
override fun onPlayerStateChanged(state: MusicPlayerState) {
func.onPlayerStateChanged?.invoke(state)
}

override fun onDownloadTrack(isSuccess: Boolean) {
func.onDownloadTrack?.invoke(isSuccess)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package weian.cheng.mediaplayerwithexoplayer

import android.content.Context
import android.net.ConnectivityManager
import android.net.Uri
import android.util.Log
import com.google.android.exoplayer2.ExoPlaybackException
Expand Down Expand Up @@ -40,7 +41,10 @@ class ExoPlayerWrapper(private val context: Context): IMusicPlayer {

private var listener: PlayerEventListener ?= null

override fun play(uri: String) {
override fun play(uri: String): Boolean {
if (!isNetworkAvailable())
return false

if (playerState == Play) {
// TODO: find out a appropriate exception or make one.
throw Exception("now is playing")
Expand All @@ -49,9 +53,10 @@ class ExoPlayerWrapper(private val context: Context): IMusicPlayer {
initExoPlayer(uri)
exoPlayer.playWhenReady = true
setPlayerState(Play)
return true
}

override fun play() {
override fun play(): Boolean {
when (isPlaying) {
true -> {
timer.pause()
Expand All @@ -72,6 +77,7 @@ class ExoPlayerWrapper(private val context: Context): IMusicPlayer {
setPlayerState(Play)
}
exoPlayer.playWhenReady = !isPlaying
return true
}

override fun stop() {
Expand Down Expand Up @@ -106,7 +112,9 @@ class ExoPlayerWrapper(private val context: Context): IMusicPlayer {

override fun getPlayerState() = playerState

override fun writeToFile(uri: String): Boolean {
override fun writeToFile(url: String, filePath: String): Boolean {
val downloadThread = DownloadHandler(url, filePath, listener)
downloadThread.start()
return true
}

Expand All @@ -121,6 +129,14 @@ class ExoPlayerWrapper(private val context: Context): IMusicPlayer {
}
}

private fun isNetworkAvailable(): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (connectivityManager.activeNetworkInfo == null) {
return false
}
return true
}

private fun initExoPlayer(url: String) {
Log.i(tag, "initExoPlayer")
val meter = DefaultBandwidthMeter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ interface IMusicPlayer {
/**
* Start playing a music.
* This function will play the music which is specified with an URI.
* If playing is failed, the function returns false.
*/
fun play(uri: String)
fun play(uri: String): Boolean

/**
* This function is also about play the music, but when the music is playing,
* executing this function will pause the music.
* If the music is pausing, executing this function will resume the music.
* If playing is failed, the function returns false.
*/
fun play()
fun play(): Boolean

/**
* stop playing the music.
Expand Down Expand Up @@ -58,7 +60,7 @@ interface IMusicPlayer {
* Return true is that writing file successful.
* Return false is that writing file unsuccessful.
*/
fun writeToFile(uri: String): Boolean
fun writeToFile(url: String, filePath: String): Boolean

/**
* The function is used to set up an event listener which monitor the activity of music player.
Expand Down

0 comments on commit 87867b6

Please sign in to comment.