23
23
*/
24
24
package com.lb.video_trimmer_library.view
25
25
26
+ import android.annotation.SuppressLint
26
27
import android.content.Context
27
28
import android.graphics.Bitmap
29
+ import android.graphics.BitmapFactory
28
30
import android.graphics.Canvas
29
31
import android.media.MediaMetadataRetriever
30
32
import android.media.ThumbnailUtils
@@ -33,54 +35,59 @@ import android.os.Build.VERSION
33
35
import android.os.Build.VERSION_CODES
34
36
import android.util.AttributeSet
35
37
import android.util.LongSparseArray
36
- import android.util.TypedValue
37
38
import android.view.View
38
39
import com.lb.video_trimmer_library.utils.BackgroundExecutor
39
40
import com.lb.video_trimmer_library.utils.UiThreadExecutor
40
41
41
- open class TimeLineView @JvmOverloads constructor(context : Context , attrs : AttributeSet ? , defStyleAttr : Int = 0 ) : View(context, attrs, defStyleAttr) {
42
+ open class TimeLineView @JvmOverloads constructor(context : Context , attrs : AttributeSet ? , defStyleAttr : Int = 0 ) :
43
+ View (context, attrs, defStyleAttr) {
42
44
private var videoUri: Uri ? = null
43
45
@Suppress(" LeakingThis" )
44
- private var heightView: Int = initHeightView()
45
46
private var bitmapList: LongSparseArray <Bitmap >? = null
46
47
47
- open fun initHeightView (): Int = TypedValue .applyDimension(TypedValue .COMPLEX_UNIT_DIP , 40f , context.resources.displayMetrics).toInt().coerceAtLeast(1 )
48
-
49
- override fun onMeasure (widthMeasureSpec : Int , heightMeasureSpec : Int ) {
50
- val minW = paddingLeft + paddingRight + suggestedMinimumWidth
51
- val w = View .resolveSizeAndState(minW, widthMeasureSpec, 1 )
52
- val minH = paddingBottom + paddingTop + heightView
53
- val h = View .resolveSizeAndState(minH, heightMeasureSpec, 1 )
54
- setMeasuredDimension(w, h)
55
- }
56
-
57
48
override fun onSizeChanged (w : Int , h : Int , oldW : Int , oldH : Int ) {
58
49
super .onSizeChanged(w, h, oldW, oldH)
59
50
if (w != oldW)
60
- getBitmap(w)
51
+ getBitmap(w, h )
61
52
}
62
53
63
- private fun getBitmap (viewWidth : Int ) {
54
+ private fun getBitmap (viewWidth : Int , viewHeight : Int ) {
55
+ // if (isInEditMode)
56
+ // return
57
+ // Set thumbnail properties (Thumbs are squares)
58
+ val thumbSize = viewHeight
59
+ val numThumbs = Math .ceil((viewWidth.toFloat() / thumbSize).toDouble()).toInt()
60
+ if (isInEditMode) {
61
+ val bitmap = ThumbnailUtils .extractThumbnail(
62
+ BitmapFactory .decodeResource(resources, android.R .drawable.sym_def_app_icon)!! , thumbSize, thumbSize
63
+ )
64
+ bitmapList = LongSparseArray ()
65
+ for (i in 0 until numThumbs)
66
+ bitmapList!! .put(i.toLong(), bitmap)
67
+ return
68
+ }
69
+ BackgroundExecutor .cancelAll(" " , true )
64
70
BackgroundExecutor .execute(object : BackgroundExecutor .Task (" " , 0L , " " ) {
65
71
override fun execute () {
66
72
try {
67
73
val thumbnailList = LongSparseArray <Bitmap >()
68
74
val mediaMetadataRetriever = MediaMetadataRetriever ()
69
75
mediaMetadataRetriever.setDataSource(context, videoUri)
70
76
// Retrieve media data
71
- val videoLengthInMs = (Integer .parseInt(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever .METADATA_KEY_DURATION )) * 1000 ).toLong()
72
- // Set thumbnail properties (Thumbs are squares)
73
- val thumbSize = heightView
74
- val numThumbs = Math .ceil((viewWidth.toFloat() / thumbSize).toDouble()).toInt()
77
+ val videoLengthInMs =
78
+ mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever .METADATA_KEY_DURATION ).toLong() * 1000L
75
79
val interval = videoLengthInMs / numThumbs
76
80
for (i in 0 until numThumbs) {
77
- var bitmap: Bitmap ?
78
- bitmap = if (VERSION .SDK_INT >= VERSION_CODES .O_MR1 )
79
- mediaMetadataRetriever.getScaledFrameAtTime(i * interval, MediaMetadataRetriever .OPTION_CLOSEST_SYNC , thumbSize, thumbSize)
80
- else
81
- mediaMetadataRetriever.getFrameAtTime(i * interval, MediaMetadataRetriever .OPTION_CLOSEST_SYNC )
81
+ var bitmap: Bitmap ? = if (VERSION .SDK_INT >= VERSION_CODES .O_MR1 )
82
+ mediaMetadataRetriever.getScaledFrameAtTime(
83
+ i * interval, MediaMetadataRetriever .OPTION_CLOSEST_SYNC , thumbSize, thumbSize
84
+ )
85
+ else mediaMetadataRetriever.getFrameAtTime(
86
+ i * interval,
87
+ MediaMetadataRetriever .OPTION_CLOSEST_SYNC
88
+ )
82
89
if (bitmap != null )
83
- bitmap = ThumbnailUtils .extractThumbnail(bitmap, thumbSize, thumbSize) // Bitmap.createScaledBitmap(bitmap, thumbSize, thumbSize, false);
90
+ bitmap = ThumbnailUtils .extractThumbnail(bitmap, thumbSize, thumbSize)
84
91
thumbnailList.put(i.toLong(), bitmap)
85
92
}
86
93
mediaMetadataRetriever.release()
@@ -101,13 +108,14 @@ open class TimeLineView @JvmOverloads constructor(context: Context, attrs: Attri
101
108
}, 0L )
102
109
}
103
110
111
+ @SuppressLint(" DrawAllocation" )
104
112
override fun onDraw (canvas : Canvas ) {
105
113
super .onDraw(canvas)
106
114
if (bitmapList != null ) {
107
115
canvas.save()
108
116
var x = 0
109
- for (i in 0 until bitmapList!! .size()) {
110
- val bitmap = bitmapList!! .get(i.toLong() )
117
+ for (i in 0L until bitmapList!! .size()) {
118
+ val bitmap = bitmapList!! .get(i)
111
119
if (bitmap != null ) {
112
120
canvas.drawBitmap(bitmap, x.toFloat(), 0f , null )
113
121
x + = bitmap.width
0 commit comments