Procházet zdrojové kódy

New: Integrate movie player and music player to movie edit activity

liweihao před 6 roky
rodič
revize
cd4ebb0480

+ 1 - 0
src/main/java/com/bomostory/sceneeditmodule/basicdata/DataParser.kt

@@ -26,6 +26,7 @@ object DataParser {
             music.name = cursor.getString(0)
             music.path = cursor.getString(1)
             music.duration = cursor.getString(2).toLong()
+            music.endTime = cursor.getString(2).toLong()
             val file = File(music.path)
             if (!paths.contains(file.path)) {
                 musics.add(music)

+ 3 - 3
src/main/java/com/bomostory/sceneeditmodule/basicdata/Music.kt

@@ -2,12 +2,12 @@ package com.bomostory.sceneeditmodule.basicdata
 
 class Music {
     var name: String? = null
-    var originPath:String? = null
     var path: String? = null
     var offsetTime: Long = 0
     var startTime: Long = 0
-    var endTime:Long = 0
+    var endTime: Long = 0
     var duration: Long = 0
     var volume: Float = 0.5f
-    var isLoop:Boolean= false
+    var isLoop: Boolean = false
+    var loopDuration: Long = 0
 }

+ 74 - 51
src/main/java/com/bomostory/sceneeditmodule/screen/movie/MovieEditActivity.kt

@@ -24,11 +24,11 @@ import com.bomostory.sceneeditmodule.screen.movie.music.MusicEditDialog
 import com.bomostory.sceneeditmodule.screen.movie.music.MusicSelectDialog
 import com.bomostory.sceneeditmodule.screen.movie.music.MusicSelectFragment
 import com.bomostory.sceneeditmodule.share.ShareDialog
-import com.bomostory.sceneeditmodule.utils.MoviePlayer
-import com.bomostory.sceneeditmodule.utils.MusicPlayer
 import com.bomostory.sceneeditmodule.screen.view.AudioTrackGroupView
 import com.bomostory.sceneeditmodule.screen.view.MovieSelectView
 import com.bomostory.sceneeditmodule.share.ExportPdfDialog
+import com.bomostory.sceneeditmodule.utils.MoviePlayerV2
+import com.bomostory.sceneeditmodule.utils.MusicPlayerV2
 import com.example.exportmedia.MediaHelper
 import com.example.tfat.myapplication.R
 import com.google.gson.Gson
@@ -55,23 +55,28 @@ class MovieEditActivity : AppCompatActivity(),
     }
 
     override fun onMusicPreCastClick(music: Music) {
-        musicPlayer.stop()
-        musicPlayer.clear()
-        musicPlayer.add(music)
-        musicPlayer.play()
+        musicPlayer.apply {
+            this.music = music
+            stop()
+            init()
+            start()
+        }
     }
 
     override fun onMusicPlayClick(music: Music, startPosition: Int) {
-        musicPlayer.clear()
-        musicPlayer.add(music)
-        musicPlayer.playChangedListener = object : MusicPlayer.OnPlayChangedListener {
-            override fun onPlayChanged(music: Music, position: Int) {
-                runOnUiThread {
-                    musicEditDialog?.currentPosition = position
+        musicPlayer.apply {
+            this.music = music
+            playChangedListener = object : MusicPlayerV2.OnPlayChangedListener {
+                override fun OnPlayChanged(position: Int) {
+                    runOnUiThread {
+                        musicEditDialog?.currentPosition = position
+                    }
                 }
             }
+            init()
+            seekTo(startPosition)
+            start()
         }
-        musicPlayer.play(startPosition)
     }
 
     override fun onMusicVolumeChanged(volume: Float) {
@@ -87,30 +92,37 @@ class MovieEditActivity : AppCompatActivity(),
     }
 
     override fun onMusicEditFinish(music: Music) {
-        viewModel.exportEditAudio(music)
-//        if (music.endTime - music.startTime > moviePlayer.totalPeriod) {
-//            music.endTime = music.startTime + moviePlayer.totalPeriod
-//        }
-//
-//        val builder = AudioEditor.Builder(mediaHelper)
-//        builder.editAudioFile = File(music.path)
-//        builder.startTime = TimeUtils.getEncodeTimeFormt(music.startTime)
-//        builder.endTime = TimeUtils.getEncodeTimeFormt(music.endTime)
-//        builder.volume = music.volume
-//
-//        val fileName = "test${System.currentTimeMillis()}.mp3"
-//        val outputFile = File(Environment.getExternalStorageDirectory(), fileName)
-//        val audioEditor = builder.build()
-//        audioEditor.output(outputFile).subscribe({
-//        }, {
-//        })
+        //TODO change path to correct path
+        val outputFile = File(Environment.getExternalStorageDirectory(), "test${System.currentTimeMillis()}.mp3")
+
+        val pd = ProgressDialog(this).apply {
+            setMessage("progressing")
+            setCancelable(false)
+        }
 
+        viewModel.exportEditAudio(music, outputFile)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .doOnSubscribe {
+                    pd.show()
+                }
+                .doFinally {
+                    pd.dismiss()
+                }
+                .subscribe({
+                    music.path = outputFile.path
+
+                    val musics: ArrayList<Music> = viewModel.musicListLiveData.value as ArrayList<Music>
+                    musics[musics.indexOf(viewModel.musicLiveData.value)] = music
+                    viewModel.musicListLiveData.value = musics
+                    viewModel.musicLiveData.value = music
+                }, {
+
+                })
     }
 
     override fun onDismiss(dialog: DialogInterface?) {
         musicPlayer.stop()
-        musicPlayer.release()
-
         delayedHide(100)
     }
 
@@ -134,9 +146,9 @@ class MovieEditActivity : AppCompatActivity(),
         hide()
     }
 
-    private val moviePlayer = MoviePlayer()
+    private val moviePlayer = MoviePlayerV2()
 
-    private val musicPlayer = MusicPlayer()
+    private val musicPlayer = MusicPlayerV2()
 
     private val mediaHelper = MediaHelper()
 
@@ -165,7 +177,7 @@ class MovieEditActivity : AppCompatActivity(),
         })
         viewModel.storyPeriodLiveData.observe(this, Observer {
             movieEditView.period = it ?: 0
-            moviePlayer.totalPeriod = it ?: 0
+            moviePlayer.period = it ?: 0
         })
         viewModel.sceneLiveData.observe(this, Observer {
             movieView.scene = it
@@ -173,7 +185,7 @@ class MovieEditActivity : AppCompatActivity(),
         viewModel.musicListLiveData.observe(this, Observer {
             movieEditView.musics = it as ArrayList<Music>
             movieEditView.isAudioTrackGroupViewVisible = it.isNotEmpty()
-            moviePlayer.musics = it
+            moviePlayer.musicList = it
             moviePlayer.init()
 
         })
@@ -194,7 +206,7 @@ class MovieEditActivity : AppCompatActivity(),
         movieEditView.onSeekBarChangeListener = object : SeekBar.OnSeekBarChangeListener {
             override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                 if (fromUser) {
-                    moviePlayer.seekTo(progress)
+                    moviePlayer.seekTo(progress.toLong())
                 }
             }
 
@@ -218,11 +230,14 @@ class MovieEditActivity : AppCompatActivity(),
         }
         movieEditView.onAudioTrackScrollListener = object : AudioTrackGroupView.OnAudioTrackScrollListener {
             override fun onAudioTrackScroll(position: Int, scrollRatio: Double) {
-                val musics: ArrayList<Music> = viewModel.musicListLiveData.value as ArrayList<Music>
-                viewModel.sceneLiveData.value?.record?.period?.let {
-                    musics[position].offsetTime = (it * scrollRatio).toLong()
-                }
-                viewModel.musicListLiveData.value = musics
+                viewModel.musicListLiveData.value?.get(position)?.offsetTime = ((viewModel.storyPeriodLiveData.value
+                        ?: 0) * scrollRatio).toLong()
+            }
+        }
+        movieEditView.onAudioTrackLoopScrollListener = object : AudioTrackGroupView.OnAudioTrackScrollListener {
+            override fun onAudioTrackScroll(position: Int, scrollRatio: Double) {
+                viewModel.musicListLiveData.value?.get(position)?.loopDuration = ((viewModel.storyPeriodLiveData.value
+                        ?: 0) * scrollRatio).toLong()
             }
         }
         movieEditView.onLoopSwitchChangedListener = CompoundButton.OnCheckedChangeListener { _, isChecked ->
@@ -233,26 +248,34 @@ class MovieEditActivity : AppCompatActivity(),
             viewModel.musicListLiveData.value = musics
         }
 
-        moviePlayer.moviePlayListener = object : MoviePlayer.OnMoviePlayListener {
+        moviePlayer.moviePlayListener = object : MoviePlayerV2.OnMoviePlayListener {
             override fun onMovieSceneUpdate(scene: Scene) {
-                if (viewModel.sceneLiveData.value != scene) {
-                    viewModel.sceneLiveData.value = scene
+                runOnUiThread {
+                    if (viewModel.sceneLiveData.value != scene) {
+                        viewModel.sceneLiveData.value = scene
+                    }
                 }
             }
 
             override fun onMoviePlayComplete() {
-                viewModel.project?.story?.let {
-                    viewModel.sceneLiveData.value = it.scenes[0]
+                runOnUiThread {
+                    viewModel.project?.story?.let {
+                        viewModel.sceneLiveData.value = it.scenes[0]
+                    }
+                    movieEditView.isBtnPanelEnable = true
                 }
-                movieEditView.isBtnPanelEnable = true
             }
 
             override fun onMoviePlayViewUpdate(x: Int) {
-                movieView.x = x
+                runOnUiThread {
+                    movieView.x = x
+                }
             }
 
             override fun onMoviePlayTimeUpdate(time: Long) {
-                movieEditView.playTime = time
+                runOnUiThread {
+                    movieEditView.playTime = time
+                }
             }
         }
 
@@ -277,7 +300,7 @@ class MovieEditActivity : AppCompatActivity(),
     }
 
     private fun playMovie(view: View) {
-        moviePlayer.play()
+        moviePlayer.start()
         movieEditView.isBtnPanelEnable = false
     }
 

+ 4 - 20
src/main/java/com/bomostory/sceneeditmodule/screen/movie/MovieEditViewModel.kt

@@ -4,13 +4,11 @@ import android.arch.lifecycle.MutableLiveData
 import android.arch.lifecycle.ViewModel
 import android.content.ContentResolver
 import android.media.MediaMetadataRetriever
-import android.os.Environment
 import com.bomostory.sceneeditmodule.basicdata.*
 import com.bomostory.sceneeditmodule.utils.TimeUtils
 import com.example.exportmedia.MediaHelper
 import com.example.exportmedia.audio.AudioEditor
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.schedulers.Schedulers
+import io.reactivex.Observable
 import java.io.File
 
 class MovieEditViewModel : ViewModel() {
@@ -55,7 +53,7 @@ class MovieEditViewModel : ViewModel() {
         musicSource.device = DataParser.parseMusic(contentResolver, libMusicPaths)
     }
 
-    fun exportEditAudio(music: Music) {
+    fun exportEditAudio(music: Music, outputFile: File): Observable<String> {
         if (music.endTime - music.startTime > storyPeriodLiveData.value ?: 0) {
             music.endTime = music.startTime + (storyPeriodLiveData.value ?: 0)
         }
@@ -66,23 +64,8 @@ class MovieEditViewModel : ViewModel() {
         audioEditorBuilder.endTime = TimeUtils.getEncodeTimeFormt(music.endTime)
         audioEditorBuilder.volume = music.volume
 
-        //TODO change path to correct path
-        val outputFile = File(Environment.getExternalStorageDirectory(), "test${System.currentTimeMillis()}.mp3")
-
         val audioEditor = audioEditorBuilder.build()
-        audioEditor.output(outputFile)
-                .subscribeOn(Schedulers.io())
-                .observeOn(AndroidSchedulers.mainThread())
-                .subscribe({
-                    music.path = outputFile.path
-
-                    val musics: ArrayList<Music> = musicListLiveData.value as ArrayList<Music>
-                    musics[musics.indexOf(musicLiveData.value)] = music
-                    musicListLiveData.value = musics
-                    musicLiveData.value = music
-                }, {
-
-                })
+        return audioEditor.output(outputFile)
     }
 
     private fun parseThemeMusic(project: Project): ArrayList<Music> {
@@ -100,6 +83,7 @@ class MovieEditViewModel : ViewModel() {
             music.name = file.name
             music.path = file.path
             music.duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toLong()
+            music.endTime = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toLong()
             musics.add(music)
         }
         return musics

+ 4 - 2
src/main/java/com/bomostory/sceneeditmodule/screen/movie/music/MusicEditDialog.kt

@@ -83,9 +83,9 @@ class MusicEditDialog : DialogFragment() {
         return inflater.inflate(R.layout.fragment_music_edit_dialog, container, false).apply {
             editMusic?.let {
                 musicName.text = it.name
-                musicLength.text = getString(R.string.music_length, TimeUtils.getPlayMovieTimeFormat(it.duration))
+                musicLength.text = getString(R.string.music_length, TimeUtils.getPlayMovieTimeFormat((it.endTime - it.startTime)))
                 startTime.text = TimeUtils.getPlayMovieTimeFormat(0)
-                endTime.text = TimeUtils.getPlayMovieTimeFormat(it.duration)
+                endTime.text = TimeUtils.getPlayMovieTimeFormat(it.endTime)
                 volumeSeekBar.progress = (it.volume * volumeSeekBar.max).toInt()
                 volumeText.text = "${volumeSeekBar.progress} %"
 
@@ -148,10 +148,12 @@ class MusicEditDialog : DialogFragment() {
                     editMusic?.apply {
                         startTime = (headScrollRatio * duration).toLong()
                         endTime = (endScrollRatio * duration).toLong()
+                        duration = endTime - startTime
                         volume = volumeSeekBar.progress.toFloat() / volumeSeekBar.max.toFloat()
 
                         listener?.onMusicEditFinish(this)
                     }
+                    dismiss()
                 }
             }
         }

+ 9 - 1
src/main/java/com/bomostory/sceneeditmodule/screen/view/AudioTrackGroupView.kt

@@ -52,6 +52,8 @@ class AudioTrackGroupView : ConstraintLayout {
 
     var onAudioTrackScrollListener: OnAudioTrackScrollListener? = null
 
+    var onAudioTrackLoopScrollListener: OnAudioTrackScrollListener? = null
+
     constructor(context: Context) : super(context) {
         initView()
     }
@@ -136,9 +138,10 @@ class AudioTrackGroupView : ConstraintLayout {
         inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
             fun bind(p1: Int) {
                 itemView.apply {
+
                     loopAudioTrackView.innerWidthRatio =
                             if (musics[p1].duration >= scenePeriod) 1f
-                            else (musics[p1].duration).toFloat() / scenePeriod.toFloat()
+                            else musics[p1].duration.toFloat() / scenePeriod.toFloat()
 
                     musics[p1].name?.let {
                         loopAudioTrackView.innerText = it
@@ -156,6 +159,11 @@ class AudioTrackGroupView : ConstraintLayout {
                             onAudioTrackScrollListener?.onAudioTrackScroll(p1, scrollRatio)
                         }
                     }
+                    loopAudioTrackView.onLoopScrollListener = object : LoopAudioTrackView.OnLoopScrollListener {
+                        override fun onScroll(scrollRatio: Double) {
+                            onAudioTrackLoopScrollListener?.onAudioTrackScroll(p1, scrollRatio)
+                        }
+                    }
                 }
             }
         }

+ 5 - 0
src/main/java/com/bomostory/sceneeditmodule/screen/view/MovieEditView.kt

@@ -81,6 +81,11 @@ class MovieEditView : ConstraintLayout {
             audioTrackGroupView.onAudioTrackScrollListener = value
         }
 
+    var onAudioTrackLoopScrollListener: AudioTrackGroupView.OnAudioTrackScrollListener? = null
+        set(value) {
+            audioTrackGroupView.onAudioTrackLoopScrollListener = value
+        }
+
     var onDeleteMusicClickListener: OnClickListener? = null
         set(value) {
             movieEditBtnPanel.onDeleteMusicClickListener = value

+ 0 - 143
src/main/java/com/bomostory/sceneeditmodule/utils/MoviePlayer.kt

@@ -1,143 +0,0 @@
-package com.bomostory.sceneeditmodule.utils
-
-import com.bomostory.sceneeditmodule.basicdata.Music
-import com.bomostory.sceneeditmodule.basicdata.Scene
-import com.bomostory.sceneeditmodule.basicdata.Story
-import io.reactivex.Observable
-import io.reactivex.Observer
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.disposables.Disposable
-import io.reactivex.schedulers.Schedulers
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicLong
-
-class MoviePlayer {
-    interface OnMoviePlayListener {
-        fun onMovieSceneUpdate(scene: Scene)
-        fun onMoviePlayViewUpdate(x: Int)
-        fun onMoviePlayTimeUpdate(time: Long)
-        fun onMoviePlayComplete()
-    }
-
-    companion object {
-        const val INTERVAL_PERIOD: Long = 1
-    }
-
-    var story: Story? = null
-
-    var totalPeriod = 0L
-
-    var musicPlayer = MusicPlayer()
-
-    var musics = ArrayList<Music>()
-    set(value) {
-        musicPlayer.musics = value
-    }
-
-    var moviePlayListener: OnMoviePlayListener? = null
-    private val lastTick = AtomicLong(0L)
-    private var disposable: Disposable? = null
-
-    fun addMusic(music: Music) {
-        musicPlayer.add(music)
-    }
-
-    fun removeMusic(music: Music) {
-        musicPlayer.remove(music)
-    }
-
-    fun init() {
-        disposable?.apply {
-            if (!isDisposed) {
-                dispose()
-            }
-        }
-        moviePlayListener?.onMoviePlayViewUpdate(0)
-        moviePlayListener?.onMoviePlayTimeUpdate(0)
-        lastTick.set(0)
-        musicPlayer.stop()
-    }
-
-    fun play() {
-        Observable.interval(INTERVAL_PERIOD, TimeUnit.MILLISECONDS)
-                .map {
-                    lastTick.getAndIncrement()
-                }
-                .subscribeOn(Schedulers.io())
-                .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(object : Observer<Long> {
-                    override fun onComplete() {
-                        init()
-                        moviePlayListener?.onMoviePlayComplete()
-                    }
-
-                    override fun onError(e: Throwable) {
-                    }
-
-                    override fun onSubscribe(d: Disposable) {
-                        disposable = d
-                        musicPlayer.play()
-                    }
-
-                    override fun onNext(t: Long) {
-                        story?.apply {
-
-                            updateMovie(t)
-
-                            if (t > (totalPeriod / INTERVAL_PERIOD)) {
-                                disposable?.dispose()
-                                onComplete()
-                            }
-                        }
-                    }
-                })
-    }
-
-    fun pause() {
-        disposable?.dispose()
-        musicPlayer.pause()
-    }
-
-    fun seekTo(mSec: Int?) {
-        mSec?.let {
-            lastTick.set(it.toLong())
-            updateMovie(mSec.toLong())
-            musicPlayer.seekTo(it)
-        }
-    }
-
-    private fun updateMovie(t: Long) {
-        val scene = getScene(t)
-        scene?.apply {
-            moviePlayListener?.onMovieSceneUpdate(this)
-            record?.let {
-                for (track in it.tracks) {
-                    if (track.time == t) {
-                        moviePlayListener?.onMoviePlayViewUpdate(track.positionX)
-                    }
-                }
-            }
-        }
-        moviePlayListener?.onMoviePlayTimeUpdate(t)
-    }
-
-    private fun getScene(t: Long): Scene? {
-        var currentScene: Scene? = null
-        var startPeriod = 0L
-        var endPeriod = 0L
-
-        story?.apply {
-            for (scene in scenes) {
-                scene.record?.apply {
-                    endPeriod += period
-                    if (t in startPeriod..endPeriod) {
-                        currentScene = scene
-                        startPeriod = endPeriod
-                    }
-                }
-            }
-        }
-
-        return currentScene
-    }
-}

+ 176 - 0
src/main/java/com/bomostory/sceneeditmodule/utils/MoviePlayerV2.kt

@@ -0,0 +1,176 @@
+package com.bomostory.sceneeditmodule.utils
+
+import android.media.MediaPlayer
+import com.bomostory.sceneeditmodule.basicdata.Music
+import com.bomostory.sceneeditmodule.basicdata.Scene
+import com.bomostory.sceneeditmodule.basicdata.Story
+import java.util.*
+import kotlin.collections.ArrayList
+
+class MoviePlayerV2 {
+    interface OnMoviePlayListener {
+        fun onMovieSceneUpdate(scene: Scene)
+        fun onMoviePlayViewUpdate(x: Int)
+        fun onMoviePlayTimeUpdate(time: Long)
+        fun onMoviePlayComplete()
+    }
+
+    var moviePlayListener: OnMoviePlayListener? = null
+
+    var story: Story? = null
+
+    var period: Long = 0
+
+    var timer: Timer? = null
+
+    var currentTime: Long = 0
+
+    var isPause = false
+
+    var musicList: List<Music> = ArrayList()
+
+    var mediaPlayers = ArrayList<MediaPlayer>()
+
+    fun init() {
+        timer?.cancel()
+        timer?.purge()
+        timer = null
+
+        currentTime = 0
+
+        updateMovie()
+
+        initMediaPlayer()
+    }
+
+    fun start() {
+        if (timer == null) {
+            timer = Timer()
+            timer?.scheduleAtFixedRate(object : TimerTask() {
+                override fun run() {
+                    if (!isPause) {
+
+                        currentTime++
+
+                        updateMovie()
+
+                        tryPlayMusic()
+
+                        if (currentTime >= period) {
+                            moviePlayListener?.onMoviePlayComplete()
+                            tryStopMusic()
+                            init()
+                        }
+                    }
+                }
+            }, 0, 1)
+        } else {
+            isPause = false
+        }
+    }
+
+    fun pause() {
+        isPause = true
+
+        tryPauseMusic()
+    }
+
+    fun seekTo(currentTime: Long) {
+        this.currentTime = currentTime
+
+        updateMovie()
+
+        trySeekMusic()
+    }
+
+    private fun updateMovie() {
+        val scene = getScene(currentTime)
+        scene?.apply {
+            moviePlayListener?.onMovieSceneUpdate(this)
+            record?.let {
+                for (track in it.tracks) {
+                    if (track.time == currentTime) {
+                        moviePlayListener?.onMoviePlayViewUpdate(track.positionX)
+                    }
+                }
+            }
+        }
+        moviePlayListener?.onMoviePlayTimeUpdate(currentTime)
+    }
+
+    private fun getScene(t: Long): Scene? {
+        var currentScene: Scene? = null
+        var startPeriod = 0L
+        var endPeriod = 0L
+
+        story?.apply {
+            for (scene in scenes) {
+                scene.record?.apply {
+                    endPeriod += period
+                    if (t in startPeriod..endPeriod) {
+                        currentScene = scene
+                        startPeriod = endPeriod
+                    }
+                }
+            }
+        }
+        return currentScene
+    }
+
+    private fun initMediaPlayer() {
+        mediaPlayers.clear()
+        for (music in musicList) {
+            val mediaPlayer = MediaPlayer()
+            mediaPlayer.apply {
+                reset()
+                setDataSource(music.path)
+                isLooping = music.isLoop
+                prepare()
+            }
+            mediaPlayers.add(mediaPlayer)
+        }
+    }
+
+    private fun tryPlayMusic() {
+        for (music in musicList) {
+            val musicEndTime  = if(music.isLoop) (music.offsetTime + music.endTime - music.startTime) + music.loopDuration else (music.offsetTime + music.endTime - music.startTime)
+
+            if (currentTime in music.offsetTime..musicEndTime) {
+                if (!mediaPlayers[musicList.indexOf(music)].isPlaying) {
+                    mediaPlayers[musicList.indexOf(music)].start()
+                } else if (currentTime >= musicEndTime) {
+                    mediaPlayers[musicList.indexOf(music)].stop()
+                    mediaPlayers[musicList.indexOf(music)].prepare()
+                }
+            }
+        }
+    }
+
+    private fun tryPauseMusic() {
+        for (mediaPlayer in mediaPlayers) {
+            mediaPlayer.pause()
+        }
+    }
+
+    private fun trySeekMusic() {
+        for (music in musicList) {
+            val musicEndTime  = if(music.isLoop) (music.offsetTime + music.endTime - music.startTime) + music.loopDuration else (music.offsetTime + music.endTime - music.startTime)
+
+            if (currentTime in music.offsetTime..musicEndTime) {
+                val actualTime = if (currentTime - music.offsetTime >= music.endTime - music.startTime)((currentTime - music.offsetTime).toDouble() / (music.endTime - music.startTime)).toInt()
+                else (currentTime - music.offsetTime).toInt()
+                mediaPlayers[musicList.indexOf(music)].seekTo(actualTime)
+            } else {
+                mediaPlayers[musicList.indexOf(music)].stop()
+                mediaPlayers[musicList.indexOf(music)].prepare()
+            }
+        }
+    }
+
+    private fun tryStopMusic(){
+        for (mediaPlayer in mediaPlayers) {
+            mediaPlayer.stop()
+        }
+    }
+
+}

+ 0 - 162
src/main/java/com/bomostory/sceneeditmodule/utils/MusicPlayer.kt

@@ -1,162 +0,0 @@
-package com.bomostory.sceneeditmodule.utils
-
-import android.media.MediaPlayer
-import com.bomostory.sceneeditmodule.basicdata.Music
-import java.util.*
-import kotlin.collections.ArrayList
-
-class MusicPlayer {
-    interface OnPlayChangedListener {
-        fun onPlayChanged(music: Music, position: Int)
-    }
-
-     var musics = ArrayList<Music>()
-    private var mediaPlayers = ArrayList<MediaPlayer>()
-
-    private var isPause = false
-
-    private var timer: Timer? = null
-    var playChangedListener: OnPlayChangedListener? = null
-
-    fun add(music: Music) {
-        musics.add(music)
-    }
-
-    fun remove(music: Music) {
-        musics.remove(music)
-    }
-
-    fun clear() {
-        musics.clear()
-    }
-
-    fun play() {
-        if (!isPause) {
-            prepare()
-            for (mediaPlayer in mediaPlayers) {
-                mediaPlayer.apply {
-                    prepareAsync()
-                }
-            }
-        } else {
-            isPause = false
-            start()
-        }
-        startTimer()
-    }
-
-    fun play(position: Int) {
-        if (!isPause) {
-            prepare(position)
-
-            for (mediaPlayer in mediaPlayers) {
-                mediaPlayer.apply {
-                    prepareAsync()
-                }
-            }
-        } else {
-            isPause = false
-            seekTo(position)
-            start()
-        }
-        startTimer()
-    }
-
-    private fun prepare() {
-        mediaPlayers.clear()
-
-        for (music in musics) {
-            val mediaPlayer = MediaPlayer()
-            mediaPlayer.apply {
-                reset()
-                setDataSource(music.path)
-                setOnPreparedListener {
-                    it.start()
-                }
-                setOnCompletionListener {
-                    mediaPlayers.remove(it)
-                }
-                mediaPlayers.add(mediaPlayer)
-            }
-        }
-    }
-
-    private fun prepare(position: Int) {
-        mediaPlayers.clear()
-
-        for (music in musics) {
-            val mediaPlayer = MediaPlayer()
-            mediaPlayer.apply {
-                reset()
-                setDataSource(music.path)
-                setOnPreparedListener {
-                    it.seekTo(position)
-                    it.start()
-                }
-                setOnCompletionListener {
-                    mediaPlayers.remove(it)
-                }
-                mediaPlayers.add(mediaPlayer)
-            }
-        }
-    }
-
-
-    private fun start() {
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.apply {
-                start()
-            }
-        }
-    }
-
-    fun pause() {
-        isPause = true
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.pause()
-        }
-        timer?.cancel()
-    }
-
-    fun seekTo(mSec: Int) {
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.seekTo(mSec)
-        }
-    }
-
-    fun setVolume(volume: Float) {
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.setVolume(volume, volume)
-        }
-    }
-
-    fun stop() {
-        isPause = false
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.apply {
-                stop()
-            }
-        }
-        timer?.cancel()
-    }
-
-    fun release() {
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.apply {
-                release()
-            }
-        }
-        mediaPlayers.clear()
-    }
-
-    private fun startTimer() {
-        timer = Timer()
-        timer?.schedule(object : TimerTask() {
-            override fun run() {
-                for (mediaPlayer in mediaPlayers) {
-                    playChangedListener?.onPlayChanged(musics[mediaPlayers.indexOf(mediaPlayer)], mediaPlayer.currentPosition)
-                }
-            }
-        }, 0, 1000)
-    }
-}

+ 78 - 0
src/main/java/com/bomostory/sceneeditmodule/utils/MusicPlayerV2.kt

@@ -0,0 +1,78 @@
+package com.bomostory.sceneeditmodule.utils
+
+import android.media.MediaPlayer
+import com.bomostory.sceneeditmodule.basicdata.Music
+import java.util.*
+
+class MusicPlayerV2 {
+    interface OnPlayChangedListener {
+        fun OnPlayChanged(position: Int)
+    }
+
+    lateinit var music: Music
+
+    val mediaPlayer = MediaPlayer()
+
+    var timer: Timer? = null
+
+    var isPause = false
+
+    var playChangedListener: OnPlayChangedListener? = null
+
+    fun init() {
+        mediaPlayer.apply {
+            if (!isPause) {
+                reset()
+                setDataSource(music.path)
+                prepare()
+            }
+        }
+    }
+
+    fun start() {
+        if (!isPause) {
+            startTimer()
+        }
+        isPause = false
+        mediaPlayer.start()
+    }
+
+    fun pause() {
+        isPause = true
+        mediaPlayer.pause()
+    }
+
+    fun seekTo(mSec: Int) {
+        mediaPlayer.seekTo(mSec)
+    }
+
+    fun setVolume(volume: Float){
+        mediaPlayer.setVolume(volume, volume)
+    }
+
+    fun stop() {
+        isPause = false
+
+        timer?.cancel()
+        timer?.purge()
+        timer = null
+
+        mediaPlayer.stop()
+    }
+
+    fun release(){
+        mediaPlayer.release()
+    }
+
+    private fun startTimer() {
+        timer = Timer()
+        timer?.scheduleAtFixedRate(object : TimerTask() {
+            override fun run() {
+                if (!isPause) {
+                    playChangedListener?.OnPlayChanged(mediaPlayer.currentPosition)
+                }
+            }
+        }, 0, 1)
+    }
+
+}