-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathExternalPlayerActivity.kt
More file actions
122 lines (105 loc) · 4.4 KB
/
ExternalPlayerActivity.kt
File metadata and controls
122 lines (105 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package org.newpipe.externalplayer
import android.app.PictureInPictureParams
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Rational
import android.view.GestureDetector
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import org.newpipe.externalplayer.databinding.ActivityExternalPlayerBinding
class ExternalPlayerActivity : AppCompatActivity() {
private lateinit var binding: ActivityExternalPlayerBinding
private var serviceStarted = false
private val speeds = floatArrayOf(1.0f, 1.25f, 1.5f, 2.0f, 0.5f)
private var speedIndex = 0
private lateinit var gestureDetector: GestureDetector
private val holdSpeed = 2.0f // Speed to set on hold
private val normalSpeed = 1.0f // Normal playback speed
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityExternalPlayerBinding.inflate(layoutInflater)
setContentView(binding.root)
handleIncomingIntent(intent)
binding.enterPipButton.setOnClickListener { enterPip() }
binding.speedButton.setOnClickListener {
speedIndex = (speedIndex + 1) % speeds.size
val speed = speeds[speedIndex]
binding.speedButton.text = "${speed}x"
val intent = Intent(this, PlayerService::class.java).apply {
action = PlayerService.ACTION_PLAY
putExtra("speed", speed)
}
ContextCompat.startForegroundService(this, intent)
}
binding.subToggle.setOnClickListener {
val newText = if (binding.subToggle.text == "SUB") "SUB:OFF" else "SUB"
binding.subToggle.text = newText
}
gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent?) {
setPlaybackSpeed(holdSpeed)
}
})
binding.playerView.setOnTouchListener { _, event ->
gestureDetector.onTouchEvent(event)
if (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL) {
setPlaybackSpeed(normalSpeed)
}
false
}
}
private fun handleIncomingIntent(intent: Intent?) {
if (intent == null) return
val action = intent.action
val data: Uri? = intent.data ?: intent.getParcelableExtra(Intent.EXTRA_STREAM)
if (Intent.ACTION_VIEW == action || data != null) {
data?.let { uri ->
binding.urlText.text = uri.toString()
startServiceWithUri(uri.toString())
}
} else if (Intent.ACTION_SEND == action) {
val text = intent.getStringExtra(Intent.EXTRA_TEXT) ?: intent.getStringExtra(Intent.EXTRA_STREAM)?.toString()
text?.let {
val url = extractUrlFromText(it)
if (url != null) startServiceWithUri(url)
}
}
}
private fun startServiceWithUri(uri: String) {
val intent = Intent(this, PlayerService::class.java).apply {
action = PlayerService.ACTION_SET_URI
putExtra(PlayerService.EXTRA_URI, uri)
}
ContextCompat.startForegroundService(this, intent)
serviceStarted = true
}
private fun extractUrlFromText(text: String): String? {
val regex = "(https?://[\\w\\-._~:/?#[\\]@!$&'()*+,;=%]+)".toRegex()
return regex.find(text)?.value
}
private fun enterPip() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val ratio = Rational(binding.playerView.width.takeIf { it > 0 } ?: 16, binding.playerView.height.takeIf { it > 0 } ?: 9)
val params = PictureInPictureParams.Builder()
.setAspectRatio(ratio)
.build()
enterPictureInPictureMode(params)
}
}
override fun onUserLeaveHint() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
enterPip()
}
}
private fun setPlaybackSpeed(speed: Float) {
val intent = Intent(this, PlayerService::class.java).apply {
action = PlayerService.ACTION_PLAY
putExtra("speed", speed)
}
ContextCompat.startForegroundService(this, intent)
binding.speedButton.text = "${speed}x"
}
}