Bladeren bron

New: edit audio track view ui implement

Shan-PC\Shan 6 jaren geleden
bovenliggende
commit
9b35812c7c

+ 34 - 13
src/main/java/com/bomostory/sceneeditmodule/MovieEditActivity.kt

@@ -10,6 +10,7 @@ import android.os.Environment
 import android.os.Handler
 import android.support.v4.app.DialogFragment
 import android.support.v7.app.AppCompatActivity
+import android.util.Log
 import android.view.View
 import android.widget.CompoundButton
 import android.widget.SeekBar
@@ -40,8 +41,31 @@ class MovieEditActivity : AppCompatActivity(),
         MusicSelectFragment.OnFragmentInteractionListener,
         MusicEditDialog.OnFragmentInteractionListener {
 
-    override fun onFragmentInteraction(uri: Uri) {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    override fun onMusicStop() {
+        musicPlayer.stop()
+    }
+
+    override fun onMusicPlayClick2(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.play(startPosition)
+    }
+
+    override fun onMusicSeekTo(mSec: Int) {
+        musicPlayer.seekTo(mSec)
+    }
+
+    override fun onMusicVolumeChanged(volume: Float) {
+        musicPlayer.setVolume(volume)
     }
 
     override fun onDismiss(dialog: DialogInterface?) {
@@ -51,10 +75,10 @@ class MovieEditActivity : AppCompatActivity(),
         delayedHide(100)
     }
 
-    override fun onMusicPlayClick(path: String) {
-        musicPlayer.pause()
+    override fun onMusicPlayClick(music: Music) {
+        musicPlayer.stop()
         musicPlayer.clear()
-        musicPlayer.add(path)
+        musicPlayer.add(music)
         musicPlayer.play()
     }
 
@@ -65,9 +89,7 @@ class MovieEditActivity : AppCompatActivity(),
     override fun onMusicImportClick(music: Music) {
         musics.add(music)
         moviePlayer.init()
-        music.path?.let {
-            moviePlayer.addMusic(it)
-        }
+        moviePlayer.addMusic(music)
         movieEditView.musics = musics
 
         val dialogFragment = supportFragmentManager.findFragmentByTag(MUSIC_SELECT_DIALOG_TAG) as DialogFragment
@@ -75,6 +97,7 @@ class MovieEditActivity : AppCompatActivity(),
     }
 
     private val shareDialog = ShareDialog()
+    private var musicEditDialog: MusicEditDialog? = null
 
     private val mHideHandler = Handler()
     private val mHidePart2Runnable = Runnable {
@@ -264,16 +287,14 @@ class MovieEditActivity : AppCompatActivity(),
     }
 
     private fun editMusic(view: View) {
-        val musicEditDialog = MusicEditDialog.newInstance(Gson().toJson(musics[currentAudioPosition]))
-        musicEditDialog.show(supportFragmentManager, MUSIC_EDIT_DIALOG_TAG)
+        musicEditDialog = MusicEditDialog.newInstance(Gson().toJson(musics[currentAudioPosition]))
+        musicEditDialog?.show(supportFragmentManager, MUSIC_EDIT_DIALOG_TAG)
     }
 
     private fun deleteMusic(view: View) {
         if (currentAudioPosition in 0 until musics.size) {
             moviePlayer.init()
-            musics[currentAudioPosition].path?.let {
-                moviePlayer.removeMusic(it)
-            }
+            moviePlayer.removeMusic(musics[currentAudioPosition])
 
             musics.removeAt(currentAudioPosition)
 

+ 141 - 7
src/main/java/com/bomostory/sceneeditmodule/MusicEditDialog.kt

@@ -1,18 +1,21 @@
 package com.bomostory.sceneeditmodule
 
 import android.content.Context
-import android.net.Uri
+import android.content.DialogInterface
 import android.os.Bundle
 import android.support.v4.app.DialogFragment
 import android.support.v4.app.Fragment
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.SeekBar
 import com.bomostory.sceneeditmodule.basicdata.Music
 import com.bomostory.sceneeditmodule.utils.TimeUtils
+import com.example.audiotrack.EditAudioTrackView
 
 import com.example.tfat.myapplication.R
 import com.google.gson.Gson
+import kotlinx.android.synthetic.main.fragment_music_edit_dialog.*
 import kotlinx.android.synthetic.main.fragment_music_edit_dialog.view.*
 
 private const val ARG_PARAM1 = "editMusic"
@@ -27,9 +30,43 @@ private const val ARG_PARAM1 = "editMusic"
  *
  */
 class MusicEditDialog : DialogFragment() {
-    // TODO: Rename and change types of parameters
     private var editMusic: Music? = null
     private var listener: OnFragmentInteractionListener? = null
+    private var dismissListener: DialogInterface.OnDismissListener? = null
+
+    var currentPosition: Int = 0
+        set(value) {
+            field = value
+
+            editMusic?.let {
+                val endPosition = endScrollRatio * it.duration
+
+                var playPosition = currentPosition
+                if (currentPosition >= endPosition) {
+                    playPosition = 0
+                    listener?.onMusicStop()
+                    editAudioTrackView.playProgressDialogVisible = false
+                }
+                editAudioTrackView.playProgress = playPosition.toFloat() / it.duration
+                editAudioTrackView.playProgressText = TimeUtils.getAudioTimeFormat(playPosition.toLong())
+            }
+        }
+
+    var headScrollRatio: Double = 0.0
+        set(value) {
+            field = value
+
+            updateMusicLength()
+            updateEditAudioTrackHeadText()
+        }
+
+    var endScrollRatio: Double = 1.0
+        set(value) {
+            field = value
+
+            updateMusicLength()
+            updateEditAudioTrackEndText()
+        }
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -43,13 +80,97 @@ 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))
+                startTime.text = TimeUtils.getPlayMovieTimeFormat(0)
+                endTime.text = TimeUtils.getPlayMovieTimeFormat(it.duration)
+                volumeSeekBar.progress = (it.volume * volumeSeekBar.max).toInt()
+                volumeText.text = "${volumeSeekBar.progress} %"
+
+                play.setOnClickListener { _ ->
+                    var playPosition = currentPosition
+                    val startPosition = it.duration * headScrollRatio
+                    if (startPosition > currentPosition) {
+                        playPosition = startPosition.toInt()
+                    }
+                    listener?.onMusicPlayClick2(it, playPosition)
+
+                    editAudioTrackView.playProgressDialogVisible = true
+                    play.visibility = View.INVISIBLE
+                    pause.visibility = View.VISIBLE
+                }
+
+                pause.setOnClickListener { _ ->
+                    editAudioTrackView.playProgressDialogVisible = false
+
+                    listener?.onMusicPauseClick()
+
+                    play.visibility = View.VISIBLE
+                    pause.visibility = View.INVISIBLE
+                }
+
+                volumeSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+                    override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
+                        volumeText.text = "$p1 %"
+
+                        editMusic?.apply {
+                            volume = p1.toFloat() / volumeSeekBar.max.toFloat()
+                            listener?.onMusicVolumeChanged(volume)
+                        }
+                    }
+
+                    override fun onStartTrackingTouch(p0: SeekBar?) {
+                    }
+
+                    override fun onStopTrackingTouch(p0: SeekBar?) {
+                    }
+                })
+
+                editAudioTrackView.onHeadScrollListener = object : EditAudioTrackView.OnEditScrollListener {
+                    override fun onScroll(view: EditAudioTrackView, scrollRatio: Double) {
+                        headScrollRatio = scrollRatio
+                    }
+                }
+
+                editAudioTrackView.onEndScrollListener = object : EditAudioTrackView.OnEditScrollListener {
+                    override fun onScroll(view: EditAudioTrackView, scrollRatio: Double) {
+                        endScrollRatio = scrollRatio
+                    }
+
+                }
+
+                cancel.setOnClickListener { _ ->
+                    dismiss()
+                }
+
+            }
+        }
+    }
+
+    private fun updateEditAudioTrackHeadText() {
+        editAudioTrackView?.let {
+            editMusic?.apply {
+                val newDuration = duration * headScrollRatio
+                it.headScrollProgressText = TimeUtils.getAudioTimeFormat(newDuration.toLong())
             }
         }
     }
 
-    // TODO: Rename method, update argument and hook method into UI event
-    fun onButtonPressed(uri: Uri) {
-        listener?.onFragmentInteraction(uri)
+    private fun updateEditAudioTrackEndText() {
+        editAudioTrackView?.let {
+            editMusic?.apply {
+                val newDuration = duration * endScrollRatio
+                it.endScrollProgressText = TimeUtils.getAudioTimeFormat(newDuration.toLong())
+            }
+        }
+    }
+
+    private fun updateMusicLength() {
+        musicLength?.let {
+            editMusic?.apply {
+                val newDuration = duration * (-headScrollRatio + endScrollRatio)
+                musicLength.text = getString(R.string.music_length, TimeUtils.getPlayMovieTimeFormat(newDuration.toLong()))
+            }
+        }
     }
 
     override fun onAttach(context: Context) {
@@ -59,11 +180,21 @@ class MusicEditDialog : DialogFragment() {
         } else {
             throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
         }
+
+        if (context is DialogInterface.OnDismissListener) {
+            dismissListener = context
+        }
     }
 
     override fun onDetach() {
         super.onDetach()
         listener = null
+        dismissListener = null
+    }
+
+    override fun onDismiss(dialog: DialogInterface?) {
+        super.onDismiss(dialog)
+        dismissListener?.onDismiss(dialog)
     }
 
     /**
@@ -78,8 +209,11 @@ class MusicEditDialog : DialogFragment() {
      * for more information.
      */
     interface OnFragmentInteractionListener {
-        // TODO: Update argument type and name
-        fun onFragmentInteraction(uri: Uri)
+        fun onMusicPlayClick2(music: Music, startPosition: Int)
+        fun onMusicPauseClick()
+        fun onMusicVolumeChanged(volume: Float)
+        fun onMusicSeekTo(mSec: Int)
+        fun onMusicStop()
     }
 
     companion object {

+ 2 - 4
src/main/java/com/bomostory/sceneeditmodule/MusicSelectFragment.kt

@@ -40,7 +40,7 @@ class MusicSelectFragment : Fragment() {
 
     interface OnFragmentInteractionListener {
 
-        fun onMusicPlayClick(path: String)
+        fun onMusicPlayClick(music: Music)
 
         fun onMusicPauseClick()
 
@@ -108,9 +108,7 @@ class MusicSelectFragment : Fragment() {
                     pause.visibility = if (p1 == playPosition) View.VISIBLE else View.INVISIBLE
 
                     play.setOnClickListener {
-                        musics[p1].path?.let {
-                            listener?.onMusicPlayClick(it)
-                        }
+                        listener?.onMusicPlayClick(musics[p1])
 
                         playPosition = p1
                         notifyDataSetChanged()

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

@@ -3,7 +3,8 @@ package com.bomostory.sceneeditmodule.basicdata
 class Music {
     var name: String? = null
     var path: String? = null
-    var offsetTime:Long = 0
+    var offsetTime: Long = 0
     var startTime: Long = 0
     var duration: Long = 0
+    var volume: Float = 0.5f
 }

+ 6 - 10
src/main/java/com/bomostory/sceneeditmodule/utils/MoviePlayer.kt

@@ -1,5 +1,6 @@
 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
@@ -42,12 +43,12 @@ class MoviePlayer {
     private val lastTick = AtomicLong(0L)
     private var disposable: Disposable? = null
 
-    fun addMusic(path: String) {
-        musicPlayer.add(path)
+    fun addMusic(music: Music) {
+        musicPlayer.add(music)
     }
 
-    fun removeMusic(path: String) {
-        musicPlayer.remove(path)
+    fun removeMusic(music: Music) {
+        musicPlayer.remove(music)
     }
 
     fun init() {
@@ -80,12 +81,7 @@ class MoviePlayer {
 
                     override fun onSubscribe(d: Disposable) {
                         disposable = d
-
-                        if (lastTick.get() == 0L) {
-                            musicPlayer.play()
-                        } else {
-                            musicPlayer.start()
-                        }
+                        musicPlayer.play()
                     }
 
                     override fun onNext(t: Long) {

+ 91 - 14
src/main/java/com/bomostory/sceneeditmodule/utils/MusicPlayer.kt

@@ -1,52 +1,108 @@
 package com.bomostory.sceneeditmodule.utils
 
 import android.media.MediaPlayer
+import com.bomostory.sceneeditmodule.basicdata.Music
+import java.util.*
+import kotlin.collections.ArrayList
 
 class MusicPlayer {
-    private var musicPaths = ArrayList<String>()
+    interface OnPlayChangedListener {
+        fun onPlayChanged(music: Music, position: Int)
+    }
+
+    private var musics = ArrayList<Music>()
     private var mediaPlayers = ArrayList<MediaPlayer>()
 
-    fun add(path: String) {
-        musicPaths.add(path)
+    private var isPause = false
+
+    private var timer: Timer? = null
+    var playChangedListener: OnPlayChangedListener? = null
+
+    fun add(music: Music) {
+        musics.add(music)
     }
 
-    fun remove(path: String) {
-        musicPaths.remove(path)
+    fun remove(music: Music) {
+        musics.remove(music)
     }
 
     fun clear() {
-        musicPaths.clear()
+        musics.clear()
     }
 
     fun play() {
-        prepare()
-        for (mediaPlayer in mediaPlayers) {
-            mediaPlayer.apply {
-                prepareAsync()
+        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 (path in musicPaths) {
+        for (music in musics) {
             val mediaPlayer = MediaPlayer()
             mediaPlayer.apply {
                 reset()
-                setDataSource(path)
+                setDataSource(music.path)
                 setOnPreparedListener {
                     it.start()
                 }
                 setOnCompletionListener {
                     mediaPlayers.remove(it)
                 }
+                mediaPlayers.add(mediaPlayer)
             }
-            mediaPlayers.add(mediaPlayer)
         }
     }
 
-    fun start() {
+    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()
@@ -55,9 +111,11 @@ class MusicPlayer {
     }
 
     fun pause() {
+        isPause = true
         for (mediaPlayer in mediaPlayers) {
             mediaPlayer.pause()
         }
+        timer?.cancel()
     }
 
     fun seekTo(mSec: Int) {
@@ -66,12 +124,20 @@ class MusicPlayer {
         }
     }
 
+    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() {
@@ -82,4 +148,15 @@ class MusicPlayer {
         }
         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)
+    }
 }

+ 6 - 0
src/main/java/com/bomostory/sceneeditmodule/utils/TimeUtils.kt

@@ -9,4 +9,10 @@ object TimeUtils {
                 TimeUnit.MILLISECONDS.toMinutes(millis),
                 TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1))
     }
+
+    fun getAudioTimeFormat(millis: Long):String{
+        return String.format("%01d:%02d",
+                TimeUnit.MILLISECONDS.toMinutes(millis),
+                TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1))
+    }
 }

+ 22 - 4
src/main/res/layout/fragment_music_edit_dialog.xml

@@ -11,6 +11,7 @@
         android:layout_width="800dp"
         android:layout_height="64dp"
         android:background="#ffecb3"
+        android:textColor="#4e342e"
         android:gravity="center" />
 
     <TextView
@@ -26,11 +27,25 @@
         app:layout_constraintTop_toTopOf="parent" />
 
     <ImageButton
+        android:id="@+id/play"
         android:layout_width="24dp"
         android:layout_height="24dp"
         android:layout_marginStart="52dp"
         android:layout_marginTop="169dp"
+        android:background="@null"
+        android:src="@drawable/ic_play"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageButton
+        android:id="@+id/pause"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginStart="52dp"
+        android:layout_marginTop="169dp"
+        android:background="@null"
         android:src="@drawable/ic_pause"
+        android:visibility="invisible"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
@@ -54,10 +69,13 @@
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/musicLength"
-        app:playProgress=".5"
-        app:playProgressDialogColor="@android:color/holo_orange_light"
-        app:playProgressText="0:20"
-        app:scrollProgressDialogColor="@android:color/holo_orange_dark" />
+        app:playProgress="0"
+        app:playProgressDialogColor="#ffecb3"
+        app:playProgressText="0:00"
+        app:playProgressTextColor="#4e342e"
+        app:scrollProgressDialogColor="#633150"
+        app:scrollProgessTextColor="@android:color/white"
+        />
 
     <TextView
         android:id="@+id/startTime"

+ 1 - 1
src/main/res/values/strings.xml

@@ -5,7 +5,7 @@
     <string name="dummy_button">Dummy Button</string>
     <string name="dummy_content">DUMMY\nCONTENT</string>
 
-    <string name="music_length">Music Length</string>
+    <string name="music_length">Music Length: %1$s</string>
     <string name="volume">Volume</string>
     <string name="save">Save</string>
     <string name="cancel">Cancel</string>