473 lines
19 KiB
Kotlin
473 lines
19 KiB
Kotlin
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 org.json.JSONObject
|
|
import java.lang.Exception
|
|
import java.util.*
|
|
import kotlin.collections.ArrayList
|
|
import kotlin.collections.HashMap
|
|
|
|
object InstanceManager {
|
|
private val oauthManager : OAuthManager = OAuthManager()
|
|
|
|
private const val BASE_API_ENDPOINT: String = "/api/v1"
|
|
private const val REGISTER_CLIENT_ENDPOINT: String = "/oauth-clients/local"
|
|
private const val GET_USER_CLIENT_ENDPOINT: String = "/users/token"
|
|
private const val GET_USER_INFO_ENDPOINT: String = "/users/me"
|
|
private const val CREATE_LIVE_ENDPOINT: String = "/videos/live"
|
|
private const val GET_CATEGORY_ENDPOINT: String = "/videos/categories"
|
|
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_VIDEOS: String = "/users/me/videos"
|
|
|
|
internal const val EXTRA_DATA: String = "EXTRA_DATA"
|
|
private const val CONTENT_TYPE: String = "CONTENT_TYPE"
|
|
private const val CONTENT_DATA: String = "CONTENT_DATA"
|
|
|
|
private const val VIDEO_CHANNEL: String = "videoChannels"
|
|
private const val CHANNEL_ID: String = "id"
|
|
private const val CHANNEL_NAME: String = "displayName"
|
|
private const val VIDEO: String = "video"
|
|
private const val UUID: String = "uuid"
|
|
private const val RTMP_URL: String = "rtmpUrl"
|
|
private const val STREAM_KEY: String = "streamKey"
|
|
|
|
fun registerAccount(context: Context, url: String, username: String, password: String, listener: InstanceListener) {
|
|
val registerUrl = url + BASE_API_ENDPOINT+ REGISTER_CLIENT_ENDPOINT
|
|
val internalListener: InstanceListener = object : InstanceListener {
|
|
override fun onSuccess(args: Bundle?) {
|
|
val oauthData: OAuthData? = args?.getParcelable(EXTRA_DATA)
|
|
oauthData?.baseUrl = url
|
|
if (oauthData != null)
|
|
getUserToken(context, url, username, password,oauthData, listener)
|
|
else
|
|
listener.onError(context.getString(R.string.unknwon_error))
|
|
}
|
|
|
|
override fun onError(error: String?) {
|
|
listener.onError(error)
|
|
}
|
|
|
|
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
|
listener.onUpdateOAuthData(oauthData)
|
|
}
|
|
|
|
}
|
|
oauthManager.register(context,registerUrl,internalListener)
|
|
}
|
|
|
|
fun getUserToken(context: Context, url: String, username: String, password: String, oauthData: OAuthData, listener: InstanceListener) {
|
|
val userAccess = url + BASE_API_ENDPOINT + GET_USER_CLIENT_ENDPOINT
|
|
oauthManager.getUserToken(context, userAccess, username, password, oauthData, listener)
|
|
}
|
|
|
|
private fun refreshToken(context: Context, url: String, oauthData: OAuthData, listener: InstanceListener) {
|
|
val registerUrl = url + BASE_API_ENDPOINT+ GET_USER_CLIENT_ENDPOINT
|
|
oauthManager.refreshToken(context, registerUrl, oauthData, listener)
|
|
}
|
|
|
|
fun createLive(context: Context, url: String, oauthData: OAuthData, streamSettings: StreamSettings, listener: InstanceListener) {
|
|
if(oauthData.expires < Calendar.getInstance().timeInMillis) {
|
|
refreshToken(context,url,oauthData,object: InstanceListener {
|
|
override fun onSuccess(args: Bundle?) {
|
|
val oauth: OAuthData? = args?.getParcelable(InstanceManager.EXTRA_DATA)
|
|
if (oauth != null) {
|
|
DatabaseManager.updateCredentials(context,oauth)
|
|
listener.onUpdateOAuthData(oauth)
|
|
createLiveImpl(context, url,oauth,streamSettings,listener)
|
|
}
|
|
}
|
|
|
|
override fun onError(error: String?) {
|
|
listener.onError(error)
|
|
}
|
|
|
|
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
|
listener.onUpdateOAuthData(oauthData)
|
|
}
|
|
|
|
})
|
|
} else {
|
|
createLiveImpl(context, url, oauthData,streamSettings,listener)
|
|
}
|
|
}
|
|
|
|
private fun getStreamKey(context: Context, url: String, oauthData: OAuthData, liveId: String, listener: InstanceListener) {
|
|
val liveInfo = "$url$BASE_API_ENDPOINT$CREATE_LIVE_ENDPOINT/$liveId"
|
|
val internalListener = 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 streamData = extractStreamData(response)
|
|
if (streamData == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
val results = Bundle()
|
|
results.putParcelable(EXTRA_DATA,streamData)
|
|
listener.onSuccess(results)
|
|
}
|
|
|
|
override fun onError(error: String?) {
|
|
listener.onError(error)
|
|
}
|
|
|
|
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
|
listener.onUpdateOAuthData(oauthData)
|
|
}
|
|
|
|
}
|
|
oauthManager.get(context,liveInfo,oauthData,internalListener)
|
|
}
|
|
|
|
private fun createLiveImpl(context: Context, url: String, oauthData: OAuthData, streamSettings: StreamSettings, listener: InstanceListener) {
|
|
// val comments: Boolean, val download: Boolean, val nsfw: Boolean, val saveReplay: Boolean
|
|
val createLiveUrl = url + BASE_API_ENDPOINT + CREATE_LIVE_ENDPOINT
|
|
val data = Bundle()
|
|
val boundary = "45fcc22"
|
|
var formData: String = prepareFormData(boundary,"channelId",streamSettings.channel.toString(),false)
|
|
formData += prepareFormData(boundary,"name",streamSettings.title,false)
|
|
formData += prepareFormData(boundary,"privacy",streamSettings.privacy.toString(),false)
|
|
if(streamSettings.category != null)
|
|
formData += prepareFormData(boundary,"category",streamSettings.category.toString(),false)
|
|
if(streamSettings.language != null)
|
|
formData += prepareFormData(boundary,"language",streamSettings.language.toString(),false)
|
|
if(streamSettings.description != null)
|
|
formData += prepareFormData(boundary,"description",streamSettings.description.toString(),false)
|
|
if(streamSettings.licence != null)
|
|
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)
|
|
data.putString(CONTENT_TYPE,"multipart/form-data; boundary=$boundary")
|
|
data.putString(CONTENT_DATA,formData)
|
|
val internalListener = 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 liveId = extractLiveId(response)
|
|
if (liveId == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
getStreamKey(context,url,oauthData,liveId,listener)
|
|
}
|
|
|
|
override fun onError(error: String?) {
|
|
listener.onError(error)
|
|
}
|
|
|
|
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
|
listener.onUpdateOAuthData(oauthData)
|
|
}
|
|
|
|
}
|
|
oauthManager.post(context,createLiveUrl,oauthData,data,internalListener)
|
|
}
|
|
|
|
fun getUserChannelList(context: Context, url: String, oauthData: OAuthData, listener: InstanceListener) {
|
|
if(oauthData.expires < Calendar.getInstance().timeInMillis) {
|
|
refreshToken(context,url,oauthData,object: InstanceListener {
|
|
override fun onSuccess(args: Bundle?) {
|
|
val oauth: OAuthData? = args?.getParcelable(EXTRA_DATA)
|
|
if (oauth != null) {
|
|
listener.onUpdateOAuthData(oauth)
|
|
DatabaseManager.updateCredentials(context,oauth)
|
|
getUserChannelListImpl(context, url,oauth,listener)
|
|
}
|
|
}
|
|
|
|
override fun onError(error: String?) {
|
|
listener.onError(error)
|
|
}
|
|
|
|
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
|
listener.onUpdateOAuthData(oauthData)
|
|
}
|
|
|
|
})
|
|
} else {
|
|
getUserChannelListImpl(context, url, oauthData, listener)
|
|
}
|
|
}
|
|
|
|
private fun getUserChannelListImpl(context: Context, url: String, oauthData: OAuthData, listener: InstanceListener) {
|
|
val userInfoUrl: String = url + BASE_API_ENDPOINT + GET_USER_INFO_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 channelList = extractChannelData(response)
|
|
if (channelList == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
args.putParcelableArrayList(EXTRA_DATA, channelList)
|
|
listener.onSuccess(args)
|
|
}
|
|
|
|
override fun onError(error: String?) {
|
|
listener.onError(error)
|
|
}
|
|
|
|
override fun onUpdateOAuthData(oauthData: OAuthData) {
|
|
listener.onUpdateOAuthData(oauthData)
|
|
}
|
|
}
|
|
|
|
oauthManager.get(context,userInfoUrl,oauthData,internalListener)
|
|
}
|
|
|
|
fun getCategoryList(context: Context, url: String, listener: InstanceListener) {
|
|
val userInfoUrl: String = url + BASE_API_ENDPOINT + GET_CATEGORY_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 categoryList = extractMapData<Int>(response,0)
|
|
if (categoryList == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
categoryList[""]=0
|
|
args.putSerializable(EXTRA_DATA, categoryList)
|
|
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)
|
|
}
|
|
|
|
|
|
fun getPrivacyList(context: Context, url: String, listener: InstanceListener) {
|
|
val userInfoUrl: String = url + BASE_API_ENDPOINT + GET_PRIVACY_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 privacyList = extractMapData<Int>(response,0)
|
|
if (privacyList == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
args.putSerializable(EXTRA_DATA, privacyList)
|
|
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)
|
|
}
|
|
|
|
fun getLicencesList(context: Context, url: String, listener: InstanceListener) {
|
|
val userInfoUrl: String = url + BASE_API_ENDPOINT + GET_LICENCE_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 licencesList = extractMapData<Int>(response,0)
|
|
if (licencesList == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
licencesList[""]=0
|
|
args.putSerializable(EXTRA_DATA, licencesList)
|
|
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)
|
|
}
|
|
|
|
fun getLanguageList(context: Context, url: String, listener: InstanceListener) {
|
|
val userInfoUrl: String = url + BASE_API_ENDPOINT + GET_LANGUAGES_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 languageList = extractMapData<String>(response,"")
|
|
if (languageList == null) {
|
|
listener.onError(context.getString(R.string.json_error))
|
|
return
|
|
}
|
|
languageList[""]=""
|
|
args.putSerializable(EXTRA_DATA, languageList)
|
|
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)
|
|
|
|
if (json.has(VIDEO_CHANNEL)) {
|
|
val channelList: ArrayList<ChannelData> = ArrayList()
|
|
val channels = json.getJSONArray(VIDEO_CHANNEL)
|
|
for (i: Int in 0 until channels.length()) {
|
|
val channel = channels.getJSONObject(i)
|
|
if (channel.has(CHANNEL_NAME) && channel.has(CHANNEL_ID)) {
|
|
val name = channel.getString(CHANNEL_NAME)
|
|
val id = channel.getLong(CHANNEL_ID)
|
|
val channelData = ChannelData(id, name)
|
|
channelList.add(channelData)
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
return channelList
|
|
} else {
|
|
return null
|
|
}
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
return null
|
|
}
|
|
}
|
|
|
|
private fun extractLiveId(response: String): String? {
|
|
try {
|
|
val json = JSONObject(response)
|
|
|
|
return if(json.has(VIDEO)) {
|
|
val video = json.getJSONObject(VIDEO)
|
|
if (video.has(UUID)) {
|
|
video.getString(UUID)
|
|
} else {
|
|
null
|
|
}
|
|
} else {
|
|
null
|
|
}
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
return null
|
|
}
|
|
}
|
|
|
|
|
|
private fun extractStreamData(response: String): StreamData? {
|
|
try {
|
|
val json = JSONObject(response)
|
|
|
|
return if (json.has(RTMP_URL) && json.has(STREAM_KEY)) {
|
|
val rtmp = json.getString(RTMP_URL)
|
|
val key = json.getString(STREAM_KEY)
|
|
|
|
StreamData(rtmp,key)
|
|
|
|
} 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)
|
|
val map = HashMap<String,T>()
|
|
for(key in json.keys()) {
|
|
if (type is Int)
|
|
map[json.getString(key)] = key.toInt() as T
|
|
else if (type is String)
|
|
map[json.getString(key)] = key as T
|
|
}
|
|
map
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
null
|
|
}
|
|
}
|
|
|
|
|
|
private fun prepareFormData(boundary: String, propertyName: String, property: String, lastData: Boolean): String {
|
|
val crlf = "\r\n"
|
|
var formData = "--$boundary$crlf"
|
|
formData+="Content-Disposition: form-data; name=\"$propertyName\"$crlf$crlf"
|
|
formData+="$property$crlf"
|
|
|
|
if(lastData) {
|
|
formData += "$crlf--$boundary--$crlf"
|
|
}
|
|
|
|
return formData
|
|
}
|
|
|
|
|
|
interface InstanceListener{
|
|
fun onSuccess(args: Bundle?)
|
|
fun onError(error: String?)
|
|
fun onUpdateOAuthData(oauthData: OAuthData)
|
|
}
|
|
} |