Skip to content

Commit

Permalink
Coub added
Browse files Browse the repository at this point in the history
Resources conflicts fixed
  • Loading branch information
TalbotGooday committed Mar 2, 2020
1 parent b2503f0 commit aa758fe
Show file tree
Hide file tree
Showing 20 changed files with 253 additions and 115 deletions.
8 changes: 5 additions & 3 deletions app/src/main/java/com/gapps/videonoapi/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package com.gapps.videonoapi
import android.content.*
import android.net.Uri
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gapps.library.api.VideoService
import com.gapps.library.api.models.video.VideoPreviewModel
import com.gapps.library.ui.bottom_menu.BottomVideoController
Expand All @@ -26,7 +26,7 @@ class MainActivity : AppCompatActivity() {
private val videoUrls = listOf(
"https://www.youtube.com/watch?v=M4BSGZ07NNA",
"https://music.youtube.com/watch?v=lFMOYjVCLUo",
"https://vimeo.com/333257472",
"https://vimeo.com/259411563",
"https://rutube.ru/video/d70e62b44b8893e98e3e90a6e2c9fcd4/?pl_type=source&pl_id=18265",
"https://www.facebook.com/UFC/videos/410056389868335/",
"https://www.dailymotion.com/video/x5sxbmb",
Expand All @@ -35,7 +35,8 @@ class MainActivity : AppCompatActivity() {
"http://www.hulu.com/w/154323",
"https://ustream.tv/channel/6540154",
"https://ustream.tv/recorded/101541339",
"https://www.ted.com/talks/jill_bolte_taylor_my_stroke_of_insight"
"https://www.ted.com/talks/jill_bolte_taylor_my_stroke_of_insight",
"https://coub.com/view/um0um0"
)

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -108,6 +109,7 @@ class MainActivity : AppCompatActivity() {
setSize(model.width, model.height)
setTitle(title)
setVideoUrl(initUrl)
setProgressView(TextView(this@MainActivity).apply { text = "Loading" })
show()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class VideoAdapter(private val videoService: VideoService, private val listener:
icon_drop_down.visible()
text_preview.visibleOrGone(video.videoTitle.isNullOrBlank().not())

Picasso.get().load(video.thumbnailUrl).transform(FitThumbnailTransformation(context.getWidth(context.resources.getDimensionPixelSize(com.gapps.library.R.dimen.bv_dialog_width)))).into(image_preview)
Picasso.get().load(video.thumbnailUrl).transform(FitThumbnailTransformation(context.getWidth(context.resources.getDimensionPixelSize(com.gapps.library.R.dimen.vna_bv_dialog_width)))).into(image_preview)

text_preview.text = video.videoTitle

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class ScrollListener(private val scrollValue: Float, private val action: (Boolean) -> Unit): RecyclerView.OnScrollListener() {
var totalDy = 0f
private var totalDy = 0f

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
Expand Down
71 changes: 34 additions & 37 deletions library/src/main/java/com/gapps/library/api/Const.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.gapps.library.api

import com.gapps.library.utils.getGroupValue

//Patterns
//YouTube: https://regex101.com/r/nJzgG0/1
const val YOUTUBE_PATTERN = "(?:http(?:s)?:\\/\\/)?(?:www.)?(?:m.)?(?:music.)?youtu(?:be|.be)?(?:\\.com)?(?:(?:\\w*.?:\\/\\/)?\\w*.?\\w*-?.?\\w*\\/(?:embed|e|v|watch|.*\\/)?\\??(?:feature=\\w*\\.?\\w*)?&?(?:v=)?\\/?)([\\w\\d_-]{11})(?:\\S+)?"
Expand All @@ -17,96 +19,91 @@ const val HULU_PATTERN = "(?:http[s]?:\\/\\/)?(?:www.)?hulu\\.(?:(?:com\\/\\S*(?
const val USTREAM_PATTERN = "(?:http[s]?:\\/\\/)?(?:www\\.)?ustream.(?:com|tv)\\/(?:recorded|embed|channel)\\/?(?:([0-9]+)|(\\S+))(?:\\/\\S*)?"
//Ted: https://regex101.com/r/Cbhu4d/2
const val TED_TALKS_PATTERN = "(?:http[s]?:\\/\\/)?(?:www|embed)?\\.?ted\\.com\\/talks\\/([_a-zA-Z0-9]+)\\S*"
//Coub: https://regex101.com/r/ZoQVLa/1
const val COUB_PATTERN = "(?:http[s]?:\\/\\/)?(?:www)?\\.?coub\\.com\\/(?:embed|view|api)\\/([_a-zA-Z0-9]+)\\S*"

//Base
private const val YOUTUBE_BASE_URL = "https://www.youtube.com"
private const val VIMEO_BASE_URL = "http://vimeo.com"
private const val FACEBOOK_BASE_URL = "https://apps.facebook.com"
private const val DAILYMOTION_BASE_URL = "https://www.dailymotion.com"
private const val WISTIA_BASE_URL = "https://fast.wistia.net"
private const val RUTUBE_BASE_URL = "http://rutube.ru/api"
private const val VZAAR_BASE_URL = "https://app.vzaar.com/"
private const val HULU_BASE_URL = "https://www.hulu.com/"
private const val HULU_BASE_URL = "https://www.hulu.com"
private const val USTREAM_BASE_URL = "https://video.ibm.com/"
private const val TED_TALKS_BASE_URL = "https://www.ted.com/"
private const val TED_TALKS_BASE_URL = "https://www.ted.com"
private const val COUB_BASE_URL = "http://coub.com/"

//Info
private const val OEMBED_INFO = "/oembed"
private const val VIMEO_INFO = "/api/v2/video/"
private const val FACEBOOK_INFO = "/plugins/video/oembed"
private const val DAILYMOTION_INFO = "/services/oembed/?url=https://www.dailymotion.com/video/"
private const val WISTIA_INFO = "/oembed?url="
private const val USTREAM_INFO = "/oembed?url="
private const val TED_TALKS_INFO = "services/v1/oembed.json?url="
private const val VZAAR_INFO = "/videos/"
private const val HULU_INFO = "api/oembed.json?url="
private const val FACEBOOK_VIDEOS = "?url=https://www.facebook.com/facebook/videos/"
private const val FACEBOOK_VIDEOS = "https://www.facebook.com/facebook/videos/"
private const val DAILYMOTION_VIDEOS = "https://www.dailymotion.com/video/"
private const val HULU_VIDEOS = "http://www.hulu.com/watch/"
private const val YOUTUBE_VIDEOS = "https://www.youtube.com/watch?v="
private const val FORMAT = "format"
private const val FORMAT_JSON = "json"
private const val URL = "url"

fun String.getYoutubeInfoUrl(): String {
val id = YOUTUBE_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
val url = "$YOUTUBE_BASE_URL/watch?v=$id"
return "$YOUTUBE_BASE_URL$OEMBED_INFO?$FORMAT=$FORMAT_JSON&$URL=$url"

val id = YOUTUBE_PATTERN.getGroupValue(this, 1)
return "https://www.youtube.com/oembed?$FORMAT=$FORMAT_JSON&$URL=$YOUTUBE_VIDEOS$id"
}

fun String.getVimeoInfoUrl(): String {
val id = VIMEO_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
return "$VIMEO_BASE_URL$VIMEO_INFO$id.$FORMAT_JSON"
val id = VIMEO_PATTERN.getGroupValue(this, 1)
return "$VIMEO_BASE_URL/api/v2/video/$id.$FORMAT_JSON"
}


fun String.getFacebookInfoUrl(): String {
val id = FACEBOOK_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
return "$FACEBOOK_BASE_URL$FACEBOOK_INFO.$FORMAT_JSON$FACEBOOK_VIDEOS$id"
val id = FACEBOOK_PATTERN.getGroupValue(this, 1)
return "$FACEBOOK_BASE_URL/plugins/video/oembed.$FORMAT_JSON?$URL=$FACEBOOK_VIDEOS$id"
}

fun String.getHuluInfoUrl(): String {
val id = HULU_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
val url = "http://www.hulu.com/watch/$id"
return "$HULU_BASE_URL$HULU_INFO$url"
val id = HULU_PATTERN.getGroupValue(this, 1)
return "$HULU_BASE_URL/api/oembed.$FORMAT=$FORMAT_JSON&$URL=$HULU_VIDEOS$id"
}

fun String.getDailymotionInfoUrl(): String {
val id = DAILYMOTION_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
return "$DAILYMOTION_BASE_URL$DAILYMOTION_INFO$id"
val id = DAILYMOTION_PATTERN.getGroupValue(this, 1)
return "$DAILYMOTION_BASE_URL/services/oembed/?$URL=$DAILYMOTION_VIDEOS$id"
}

fun String.getTedTalksInfoUrl(): String {
return "$TED_TALKS_BASE_URL$TED_TALKS_INFO$this"
return "$TED_TALKS_BASE_URL/services/v1/oembed.$FORMAT_JSON?$URL=$this"
}

fun String.getCoubInfoUrl(): String {
return "$COUB_BASE_URL/api/oembed.$FORMAT_JSON?$URL=$this"
}

fun String.getWistiaInfoUrl(): String {
return "$WISTIA_BASE_URL$WISTIA_INFO$this"
return "$WISTIA_BASE_URL/oembed?$URL=$this"
}

fun String.getUstreamInfoUrl(): String {
val id = USTREAM_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
val channelId = USTREAM_PATTERN.toRegex().find(this)?.groups?.get(2)?.value
val id = USTREAM_PATTERN.getGroupValue(this, 1)
val channelId = USTREAM_PATTERN.getGroupValue(this, 2)

val url = if (id == null || this.contains("channel")) {
"https://ustream.tv/channel/${channelId ?: id}"
} else {
"https://ustream.tv/recorded/$id"
}

return "$USTREAM_BASE_URL$USTREAM_INFO$url"
return "$USTREAM_BASE_URL/oembed?$URL=$url"
}

fun String.getVzaarInfoUrl(): String {
val id = VZAAR_PATTERN.toRegex().find(this)?.groups?.get(1)?.value
val id = VZAAR_PATTERN.getGroupValue(this, 1)

return "$VZAAR_BASE_URL$VZAAR_INFO$id.$FORMAT_JSON"
return "$VZAAR_BASE_URL/videos/$id.$FORMAT_JSON"
}


fun String.getRutubeInfoUrl(): String {
val id = RUTUBE_PATTERN.toRegex().find(this)?.groups?.get(1)?.value ?: ""
val id = RUTUBE_PATTERN.getGroupValue(this, 1) ?: ""

return if (id.length < 32) {
"$RUTUBE_BASE_URL$OEMBED_INFO?$FORMAT=$FORMAT_JSON&$URL=$this"
"$RUTUBE_BASE_URL/oembed?$FORMAT=$FORMAT_JSON&$URL=$this"
} else {
"$RUTUBE_BASE_URL/video/$id/"
}
Expand Down
15 changes: 13 additions & 2 deletions library/src/main/java/com/gapps/library/api/VideoService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.gapps.library.api
import android.util.Log
import com.gapps.library.api.models.video.VideoPreviewModel
import com.gapps.library.api.models.video.base.BaseVideoResponse
import com.gapps.library.api.models.video.coub.CoubResponse
import com.gapps.library.api.models.video.dailymotion.DailymotionResponse
import com.gapps.library.api.models.video.facebook.FacebookResponse
import com.gapps.library.api.models.video.hulu.HuluResponse
Expand All @@ -16,6 +17,7 @@ import com.gapps.library.api.models.video.youtube.YoutubeResponse
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonParser
import com.google.gson.JsonParser.parseString
import kotlinx.coroutines.*
import okhttp3.OkHttpClient
import okhttp3.Request
Expand Down Expand Up @@ -72,6 +74,9 @@ class VideoService(
url.matches(TED_TALKS_PATTERN.toRegex()) -> {
videoHelper.getTedTalksInfo(url, callback)
}
url.matches(COUB_PATTERN.toRegex()) -> {
videoHelper.getCoubInfo(url, callback)
}
else -> {
callback.invoke(VideoPreviewModel.error(url, ERROR_1))
}
Expand All @@ -98,6 +103,11 @@ class VideoService(
getVideoInfo(url, url.getTedTalksInfoUrl(), TedTalksResponse::class.java, callback)
}


fun getCoubInfo(url: String, callback: (VideoPreviewModel) -> Unit) {
getVideoInfo(url, url.getCoubInfoUrl(), CoubResponse::class.java, callback)
}

fun getHuluInfo(url: String, callback: (VideoPreviewModel) -> Unit) {
getVideoInfo(url, url.getHuluInfoUrl(), HuluResponse::class.java, callback)
}
Expand Down Expand Up @@ -127,7 +137,8 @@ class VideoService(
}

fun getYoutubeInfo(url: String, callback: (VideoPreviewModel) -> Unit) {
getVideoInfo(url, url.getYoutubeInfoUrl(), YoutubeResponse::class.java, callback)
val type = YoutubeResponse::class.java
getVideoInfo(url, url.getYoutubeInfoUrl(), type, callback)
}

private fun getVideoInfo(originalUrl: String?, finalUrl: String?, type: Type?, callback: (VideoPreviewModel) -> Unit) {
Expand Down Expand Up @@ -180,7 +191,7 @@ class VideoService(
return withContext(Dispatchers.IO) {
val response = client.newCall(Request.Builder().url(url).build()).execute()
val stringBody = response.body()?.string() ?: return@withContext null
val jsonObject = JsonParser().parse(stringBody)
val jsonObject = parseString(stringBody)

return@withContext if (jsonObject.isJsonArray) {
jsonObject.asJsonArray[0]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.gapps.library.api.models.api

import com.gapps.library.api.DAILYMOTION_PATTERN
import com.gapps.library.api.models.video.dailymotion.DailymotionResponse
import com.gapps.library.utils.getGroupValue

class DailymotionVideoInfoModel : VideoInfoModel<DailymotionResponse> {
override var pattern: String = DAILYMOTION_PATTERN
override val idPattern: String
get() = pattern

override val type: Class<DailymotionResponse> = DailymotionResponse::class.java

override fun parseVideoId(url: String?): String? {
return idPattern.getGroupValue(url, 1)
}

override fun checkHostAffiliation(url: String?): Boolean {
url ?: return false

return url.matches(pattern.toRegex())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.gapps.library.api.models.api

interface VideoInfoModel<T> {
val pattern: String
val idPattern: String
val type: Class<T>

/**
*
*/
fun parseVideoId(url: String?): String?

fun checkHostAffiliation(url: String?): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class VideoPreviewModel {
const val RUTUBE = "Rutube"
const val FACEBOOK = "Facebook"
const val DAILYMOTION = "Dailymotion"
const val COUB = "Coub"
const val WISTIA = "Wistia"
const val VZAAR = "Vzaar"
const val HULU = "Hulu"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.gapps.library.api.models.video.coub


import com.gapps.library.api.COUB_PATTERN
import com.gapps.library.api.FACEBOOK_PATTERN
import com.gapps.library.api.models.video.VideoPreviewModel
import com.gapps.library.api.models.video.base.BaseVideoResponse
import com.gapps.library.utils.getGroupValue
import com.google.gson.annotations.SerializedName

data class CoubResponse(
@SerializedName("type")
val type: String = "",
@SerializedName("version")
val version: String = "",
@SerializedName("width")
val width: String = "",
@SerializedName("height")
val height: String = "",
@SerializedName("title")
val title: String = "",
@SerializedName("url")
val url: String = "",
@SerializedName("thumbnail_url")
val thumbnailUrl: String = "",
@SerializedName("thumbnail_width")
val thumbnailWidth: String = "",
@SerializedName("thumbnail_height")
val thumbnailHeight: String = "",
@SerializedName("author_name")
val authorName: String = "",
@SerializedName("channel_url")
val channelUrl: String = "",
@SerializedName("provider_name")
val providerName: String = "",
@SerializedName("provider_url")
val providerUrl: String = "",
@SerializedName("html")
val html: String = ""
): BaseVideoResponse{
override fun toPreview(url: String?): VideoPreviewModel {
return VideoPreviewModel().apply {
this.thumbnailUrl = this@CoubResponse.thumbnailUrl
this.videoTitle = this@CoubResponse.title
this.url = url
this.videoHosting = VideoPreviewModel.DAILYMOTION
this.videoId = getVideoId(url)
this.linkToPlay = "https://coub.com/embed/${videoId}"
this.width = this@CoubResponse.width.toInt()
this.height = this@CoubResponse.height.toInt()
}
}

override fun getVideoId(url: String?): String? {
url ?: return null

return COUB_PATTERN.getGroupValue(url, 1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import com.gapps.library.api.models.video.base.BaseVideoResponse
import com.google.gson.annotations.SerializedName

data class RutubeResponse(
@SerializedName("action_reason")
val actionReason: Int = 0,
@SerializedName("title")
val title: String = "",
@SerializedName("thumbnail_url")
val thumbnailUrl: String = "",
@SerializedName("source_url")
val sourceUrl: String = "",
@SerializedName("all_tags")
val allTags: List<AllTag> = listOf(),
@SerializedName("author")
Expand Down Expand Up @@ -98,12 +102,6 @@ data class RutubeResponse(
val shortDescription: String = "",
@SerializedName("show")
val show: Any? = Any(),
@SerializedName("source_url")
val sourceUrl: String = "",
@SerializedName("thumbnail_url")
val thumbnailUrl: String = "",
@SerializedName("title")
val title: String = "",
@SerializedName("track_id")
val trackId: Int = 0,
@SerializedName("tv_show_id")
Expand All @@ -128,7 +126,7 @@ data class RutubeResponse(
return VideoPreviewModel().apply {
this.videoTitle = this@RutubeResponse.title
this.thumbnailUrl = this@RutubeResponse.thumbnailUrl
this.url = this@RutubeResponse.sourceUrl
this.url = url
this.videoHosting = VideoPreviewModel.RUTUBE
this.videoId = getVideoId()
this.linkToPlay = "http://rutube.ru/play/embed/${this.videoId}"
Expand Down
Loading

0 comments on commit aa758fe

Please sign in to comment.