mirror of
https://codeberg.org/Schoumi/PeerTubeLive.git
synced 2025-02-09 08:38:48 +01:00
Manage instance live configuration: live enabled and allow replay
fixes #11
This commit is contained in:
parent
6031e37959
commit
f9ea80bb3d
@ -5,21 +5,16 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ProgressBar
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.ActivityResultCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import fr.mobdev.peertubelive.R
|
||||
import fr.mobdev.peertubelive.databinding.ChannelListBinding
|
||||
import fr.mobdev.peertubelive.databinding.CreateLiveBinding
|
||||
import fr.mobdev.peertubelive.manager.DatabaseManager
|
||||
import fr.mobdev.peertubelive.manager.InstanceManager
|
||||
import fr.mobdev.peertubelive.objects.ChannelData
|
||||
import fr.mobdev.peertubelive.objects.OAuthData
|
||||
import fr.mobdev.peertubelive.objects.StreamData
|
||||
import fr.mobdev.peertubelive.objects.StreamSettings
|
||||
import fr.mobdev.peertubelive.objects.*
|
||||
import fr.mobdev.peertubelive.utils.TranslationUtils
|
||||
import java.util.ArrayList
|
||||
|
||||
@ -35,9 +30,10 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
private lateinit var privacies: MutableMap<String, Int>
|
||||
private lateinit var languages: MutableMap<String, String>
|
||||
private lateinit var oAuthData: OAuthData
|
||||
private lateinit var configData: ConfigData
|
||||
private var inError: Boolean = false
|
||||
private var showAdvancedSettings = true
|
||||
private lateinit var binding: ChannelListBinding
|
||||
private lateinit var binding: CreateLiveBinding
|
||||
private lateinit var startLive: ActivityResultLauncher<Intent>
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -45,7 +41,7 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
|
||||
oAuthData = intent.getParcelableExtra(OAUTH_DATA)!!
|
||||
|
||||
binding = DataBindingUtil.setContentView(this,R.layout.channel_list)
|
||||
binding = DataBindingUtil.setContentView(this,R.layout.create_live)
|
||||
|
||||
binding.error.visibility = View.GONE
|
||||
binding.channelList.visibility = View.GONE
|
||||
@ -60,6 +56,7 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
binding.saveReplayInfo.visibility = View.GONE
|
||||
binding.resolution.visibility = View.GONE
|
||||
binding.resolutionList.visibility = View.GONE
|
||||
binding.liveDisabled.visibility = View.GONE
|
||||
|
||||
startLive = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
setResult(it.resultCode)
|
||||
@ -93,7 +90,9 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
val comments = binding.commentsEnabled.isChecked
|
||||
val download = binding.downloadEnabled.isChecked
|
||||
val nsfw = binding.nsfw.isChecked
|
||||
val replay = binding.saveReplay.isChecked
|
||||
var replay: Boolean? = null
|
||||
if (configData.saveReplayEnabled)
|
||||
replay = binding.saveReplay.isChecked
|
||||
|
||||
val resolution = StreamData.STREAM_RESOLUTION.values()[binding.resolutionList.selectedItemPosition]
|
||||
|
||||
@ -108,6 +107,22 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
InstanceManager.getLiveConfig(this,oAuthData.baseUrl!!,object : InstanceManager.InstanceListener {
|
||||
override fun onSuccess(args: Bundle?) {
|
||||
configData = args?.getParcelable<ConfigData>(InstanceManager.EXTRA_DATA)!!
|
||||
updateView(null)
|
||||
}
|
||||
|
||||
override fun onError(error: String?) {
|
||||
inError = true
|
||||
updateView(error)
|
||||
}
|
||||
|
||||
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
||||
this@CreateLiveActivity.oAuthData.updateData(oauthData)
|
||||
}
|
||||
})
|
||||
|
||||
InstanceManager.getCategoryList(this,oAuthData.baseUrl!!,object : InstanceManager.InstanceListener {
|
||||
override fun onSuccess(args: Bundle?) {
|
||||
val map = args?.getSerializable(InstanceManager.EXTRA_DATA)!! as Map<String, Int>
|
||||
@ -223,7 +238,16 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
|
||||
private fun updateView(error: String?) {
|
||||
if(!inError) {
|
||||
if(this::channels.isInitialized && this::categories.isInitialized && this::privacies.isInitialized && this::languages.isInitialized && this::licences.isInitialized) {
|
||||
if (this::configData.isInitialized && !configData.liveEnabled) {
|
||||
runOnUiThread {
|
||||
binding.loadingProgress.visibility = View.GONE
|
||||
binding.loadingChannels.visibility = View.GONE
|
||||
binding.liveDisabled.visibility = View.VISIBLE
|
||||
}
|
||||
return
|
||||
}
|
||||
if(this::configData.isInitialized && configData.liveEnabled && this::channels.isInitialized && this::categories.isInitialized
|
||||
&& this::privacies.isInitialized && this::languages.isInitialized && this::licences.isInitialized) {
|
||||
val channelAdapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item)
|
||||
for (channel in channels) {
|
||||
channelAdapter.add(channel.name)
|
||||
@ -264,8 +288,10 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
binding.advanceSettings.visibility = View.VISIBLE
|
||||
binding.privacy.visibility = View.VISIBLE
|
||||
binding.privacyList.visibility = View.VISIBLE
|
||||
binding.saveReplayLayout.visibility = View.VISIBLE
|
||||
binding.saveReplayInfo.visibility = View.VISIBLE
|
||||
if (configData.saveReplayEnabled) {
|
||||
binding.saveReplayLayout.visibility = View.VISIBLE
|
||||
binding.saveReplayInfo.visibility = View.VISIBLE
|
||||
}
|
||||
binding.resolution.visibility = View.VISIBLE
|
||||
binding.resolutionList.visibility = View.VISIBLE
|
||||
restoreSettings()
|
||||
@ -346,7 +372,8 @@ class CreateLiveActivity : AppCompatActivity() {
|
||||
binding.commentsEnabled.isChecked = settings.comments
|
||||
binding.downloadEnabled.isChecked = settings.download
|
||||
binding.nsfw.isChecked = settings.nsfw
|
||||
binding.saveReplay.isChecked = settings.saveReplay
|
||||
if (settings.saveReplay != null)
|
||||
binding.saveReplay.isChecked = settings.saveReplay
|
||||
binding.liveTitle.setText(settings.title)
|
||||
|
||||
if (settings.privacy != 0) {
|
||||
|
@ -330,7 +330,6 @@ class StreamActivity : AppCompatActivity() {
|
||||
if (rtmpCamera2.prepareAudio() && rtmpCamera2.prepareVideo(width,height,30, (width*height*30*0.076).toInt(),false,CameraHelper.getCameraOrientation(this))) {
|
||||
rtmpCamera2.startStream(streamData.url+"/"+streamData.key)
|
||||
} else {
|
||||
println("error")
|
||||
/**This device cant init encoders, this could be for 2 reasons: The encoder selected doesnt support any configuration setted or your device hasnt a H264 or AAC encoder (in this case you can see log error valid encoder not found) */
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,7 @@ package fr.mobdev.peertubelive.manager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import fr.mobdev.peertubelive.R
|
||||
import fr.mobdev.peertubelive.objects.ChannelData
|
||||
import fr.mobdev.peertubelive.objects.OAuthData
|
||||
import fr.mobdev.peertubelive.objects.StreamData
|
||||
import fr.mobdev.peertubelive.objects.StreamSettings
|
||||
import fr.mobdev.peertubelive.objects.*
|
||||
import org.json.JSONObject
|
||||
import java.lang.Exception
|
||||
import java.util.*
|
||||
@ -25,6 +22,7 @@ object InstanceManager {
|
||||
private const val GET_PRIVACY_ENDPOINT: String = "/videos/privacies"
|
||||
private const val GET_LICENCE_ENDPOINT: String = "/videos/licences"
|
||||
private const val GET_LANGUAGES_ENDPOINT: String = "/videos/languages"
|
||||
private const val GET_CONFIG_ENDPOINT: String = "/config"
|
||||
private const val GET_VIDEOS: String = "/users/me/videos"
|
||||
|
||||
internal const val EXTRA_DATA: String = "EXTRA_DATA"
|
||||
@ -38,6 +36,9 @@ object InstanceManager {
|
||||
private const val UUID: String = "uuid"
|
||||
private const val RTMP_URL: String = "rtmpUrl"
|
||||
private const val STREAM_KEY: String = "streamKey"
|
||||
private const val CONFIG_LIVE: String = "live"
|
||||
private const val CONFIG_LIVE_ENABLED: String = "enabled"
|
||||
private const val CONFIG_LIVE_SAVE_REPLAY: String = "allowReplay"
|
||||
|
||||
fun registerAccount(context: Context, url: String, username: String, password: String, listener: InstanceListener) {
|
||||
val registerUrl = url + BASE_API_ENDPOINT+ REGISTER_CLIENT_ENDPOINT
|
||||
@ -148,8 +149,9 @@ object InstanceManager {
|
||||
formData += prepareFormData(boundary,"licence",streamSettings.licence.toString(),false)
|
||||
formData += prepareFormData(boundary,"commentsEnabled",streamSettings.comments.toString(),false)
|
||||
formData += prepareFormData(boundary,"nsfw",streamSettings.nsfw.toString(),false)
|
||||
formData += prepareFormData(boundary,"downloadEnabled",streamSettings.download.toString(),false)
|
||||
formData += prepareFormData(boundary,"saveReplay",streamSettings.saveReplay.toString(),true)
|
||||
formData += prepareFormData(boundary,"downloadEnabled",streamSettings.download.toString(),streamSettings.saveReplay == null)
|
||||
if (streamSettings.saveReplay != null)
|
||||
formData += prepareFormData(boundary,"saveReplay",streamSettings.saveReplay.toString(),true)
|
||||
data.putString(CONTENT_TYPE,"multipart/form-data; boundary=$boundary")
|
||||
data.putString(CONTENT_DATA,formData)
|
||||
val internalListener = object: InstanceListener {
|
||||
@ -365,6 +367,36 @@ object InstanceManager {
|
||||
oauthManager.get(context,userInfoUrl,null,internalListener)
|
||||
}
|
||||
|
||||
fun getLiveConfig(context: Context, url: String, listener: InstanceListener) {
|
||||
val userInfoUrl: String = url + BASE_API_ENDPOINT + GET_CONFIG_ENDPOINT
|
||||
val internalListener : InstanceListener = object : InstanceListener {
|
||||
override fun onSuccess(args: Bundle?) {
|
||||
val response = args?.getString(EXTRA_DATA, null)
|
||||
if (response == null) {
|
||||
listener.onError(context.getString(R.string.unknwon_error))
|
||||
return
|
||||
}
|
||||
val configData = extractConfigData(response)
|
||||
if (configData == null) {
|
||||
listener.onError(context.getString(R.string.json_error))
|
||||
return
|
||||
}
|
||||
args.putParcelable(EXTRA_DATA, configData)
|
||||
listener.onSuccess(args)
|
||||
}
|
||||
|
||||
override fun onError(error: String?) {
|
||||
listener.onError(error)
|
||||
}
|
||||
|
||||
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
||||
listener.onUpdateOAuthData(oauthData)
|
||||
}
|
||||
}
|
||||
|
||||
oauthManager.get(context,userInfoUrl,null,internalListener)
|
||||
}
|
||||
|
||||
private fun extractChannelData(response: String): ArrayList<ChannelData>? {
|
||||
try {
|
||||
val json = JSONObject(response)
|
||||
@ -433,6 +465,28 @@ object InstanceManager {
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractConfigData(response: String): ConfigData? {
|
||||
try {
|
||||
val json = JSONObject(response)
|
||||
|
||||
return if (json.has(CONFIG_LIVE)) {
|
||||
val live = json.getJSONObject(CONFIG_LIVE)
|
||||
return if(live.has(CONFIG_LIVE_ENABLED) && live.has(CONFIG_LIVE_SAVE_REPLAY)) {
|
||||
val liveEnabled = live.getBoolean(CONFIG_LIVE_ENABLED)
|
||||
val saveReplayEnabled = live.getBoolean(CONFIG_LIVE_SAVE_REPLAY)
|
||||
ConfigData(liveEnabled,saveReplayEnabled)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> extractMapData(response: String, type: T): HashMap<String,T>? {
|
||||
return try {
|
||||
val json = JSONObject(response)
|
||||
|
@ -0,0 +1,31 @@
|
||||
package fr.mobdev.peertubelive.objects;
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
|
||||
class ConfigData(val liveEnabled: Boolean, val saveReplayEnabled: Boolean) : Parcelable {
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readByte() != 0.toByte(),
|
||||
parcel.readByte() != 0.toByte()
|
||||
) {
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeByte(if (liveEnabled) 1 else 0)
|
||||
dest.writeByte(if (saveReplayEnabled) 1 else 0)
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<StreamData> {
|
||||
override fun createFromParcel(parcel: Parcel): StreamData {
|
||||
return StreamData(parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<StreamData?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import android.os.Parcelable
|
||||
|
||||
class StreamSettings(
|
||||
val title: String, val channel: Long, val privacy: Int, val category: Int?, val language: String?, val licence: Int?, val description: String?,
|
||||
val comments: Boolean, val download: Boolean, val nsfw: Boolean, val saveReplay: Boolean, val resolution: StreamData.STREAM_RESOLUTION) : Parcelable {
|
||||
val comments: Boolean, val download: Boolean, val nsfw: Boolean, val saveReplay: Boolean?, val resolution: StreamData.STREAM_RESOLUTION) : Parcelable {
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readString()!!,
|
||||
parcel.readLong(),
|
||||
@ -37,7 +37,8 @@ class StreamSettings(
|
||||
parcel.writeByte(if (comments) 1 else 0)
|
||||
parcel.writeByte(if (download) 1 else 0)
|
||||
parcel.writeByte(if (nsfw) 1 else 0)
|
||||
parcel.writeByte(if (saveReplay) 1 else 0)
|
||||
if (saveReplay!= null)
|
||||
parcel.writeByte(if (saveReplay) 1 else 0)
|
||||
parcel.writeInt(resolution?.ordinal!!)
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,18 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/live_disabled"
|
||||
android:textColor="#FF0000"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/live_disabled"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_margin="5dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error"
|
@ -26,6 +26,7 @@
|
||||
<string name="stop_reason">Votre direct est terminé</string>
|
||||
<string name="ask_end_stream">Voulez-vous arrêter le direct \?</string>
|
||||
<string name="network_reason">Votre direct s\'est terminé à cause d\'un problème réseau</string>
|
||||
<string name="live_disabled">Cette instance a désactivé les directs.</string>
|
||||
<!-- buttons -->
|
||||
<string name="choose_channel">Chaîne</string>
|
||||
<string name="go_live">Démarrer le direct !</string>
|
||||
|
@ -26,6 +26,7 @@
|
||||
<string name="stop_reason">Your livestream ended</string>
|
||||
<string name="ask_end_stream">Do you want to stop the live?</string>
|
||||
<string name="network_reason">Your livestream ended because of a network problem</string>
|
||||
<string name="live_disabled">This instance has disabled livestream.</string>
|
||||
<!-- buttons -->
|
||||
<string name="choose_channel">Channel</string>
|
||||
<string name="go_live">Start livestream</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user