From c356f9b4263c81b1f7e0298029cc24ec1f819696 Mon Sep 17 00:00:00 2001 From: rimthekid Date: Sat, 18 Dec 2021 15:04:14 +0400 Subject: [PATCH] migrated to retrofit+jackson --- .idea/deploymentTargetDropDown.xml | 13 +- app/build.gradle | 10 +- .../main/java/xyz/btcland/libretube/Home.kt | 33 ++- .../java/xyz/btcland/libretube/PipedApi.kt | 15 ++ .../main/java/xyz/btcland/libretube/Player.kt | 202 +----------------- .../xyz/btcland/libretube/PlayerFragment.kt | 163 ++++++++++++-- .../xyz/btcland/libretube/RetrofitInstance.kt | 14 ++ .../xyz/btcland/libretube/TrendingAdapter.kt | 9 +- .../main/java/xyz/btcland/libretube/Video.kt | 14 -- .../xyz/btcland/libretube/VideoInPlayer.kt | 49 ----- .../xyz/btcland/libretube/obj/Channel.java | 23 ++ .../btcland/libretube/obj/ChapterSegment.kt | 9 + .../xyz/btcland/libretube/obj/Comment.java | 22 ++ .../btcland/libretube/obj/CommentsPage.java | 16 ++ .../xyz/btcland/libretube/obj/FeedItem.java | 23 ++ .../xyz/btcland/libretube/obj/PipedStream.kt | 20 ++ .../xyz/btcland/libretube/obj/Playlist.java | 23 ++ .../xyz/btcland/libretube/obj/StreamItem.kt | 16 ++ .../java/xyz/btcland/libretube/obj/Streams.kt | 31 +++ .../xyz/btcland/libretube/obj/Subtitle.kt | 11 + .../main/res/layout-land/fragment_player.xml | 108 ++++++++++ 21 files changed, 517 insertions(+), 307 deletions(-) create mode 100644 app/src/main/java/xyz/btcland/libretube/PipedApi.kt create mode 100644 app/src/main/java/xyz/btcland/libretube/RetrofitInstance.kt delete mode 100644 app/src/main/java/xyz/btcland/libretube/Video.kt delete mode 100644 app/src/main/java/xyz/btcland/libretube/VideoInPlayer.kt create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/Channel.java create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/ChapterSegment.kt create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/Comment.java create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/CommentsPage.java create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/FeedItem.java create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/PipedStream.kt create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/Playlist.java create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/StreamItem.kt create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/Streams.kt create mode 100644 app/src/main/java/xyz/btcland/libretube/obj/Subtitle.kt create mode 100644 app/src/main/res/layout-land/fragment_player.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 7427b0822..02c33d593 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -1,17 +1,6 @@ - - - - - - - - - - - @@ -23,7 +12,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index e605523ff..e6d881642 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { defaultConfig { applicationId 'xyz.btcland.libretube' - minSdk 19 + minSdk 21 targetSdk 31 versionCode 1 versionName '1.0' @@ -39,14 +39,16 @@ dependencies { implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0-rc01' implementation 'androidx.navigation:navigation-ui-ktx:2.4.0-rc01' implementation 'androidx.legacy:legacy-support-v4:1.0.0' - testImplementation 'junit:junit:' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.2' - implementation 'com.google.code.gson:gson:2.8.9' + implementation 'com.squareup.picasso:picasso:2.8' implementation 'de.hdodenhof:circleimageview:3.1.0' implementation 'com.google.android.exoplayer:exoplayer:2.16.1' implementation 'androidx.multidex:multidex:2.0.1' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-jackson:2.9.0' + } \ No newline at end of file diff --git a/app/src/main/java/xyz/btcland/libretube/Home.kt b/app/src/main/java/xyz/btcland/libretube/Home.kt index c165b39b4..a8a736feb 100644 --- a/app/src/main/java/xyz/btcland/libretube/Home.kt +++ b/app/src/main/java/xyz/btcland/libretube/Home.kt @@ -1,24 +1,27 @@ package xyz.btcland.libretube import android.os.Bundle +import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ProgressBar +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.google.gson.GsonBuilder -import com.google.gson.reflect.TypeToken + import okhttp3.* +import retrofit2.HttpException import java.io.IOException +import java.lang.Exception // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" private const val ARG_PARAM2 = "param2" - +const val TAG = "HomeFragment" /** * A simple [Fragment] subclass. * Use the [Home.newInstance] factory method to @@ -79,10 +82,10 @@ class Home : Fragment() { } private fun fetchJson(progressBar: ProgressBar, recyclerView: RecyclerView) { - val client = OkHttpClient() + //val client = OkHttpClient() fun run() { - val request = Request.Builder() +/* val request = Request.Builder() .url("http://piped-api.alefvanoon.xyz/trending?region=US") .build() client.newCall(request).enqueue(object : Callback { @@ -102,10 +105,24 @@ class Home : Fragment() { recyclerView.adapter = TrendingAdapter(trendingList) } } - - } - }) + })*/ + lifecycleScope.launchWhenCreated { + val response = try { + RetrofitInstance.api.getTrending("US") + }catch(e: IOException) { + println(e) + Log.e(TAG, "IOException, you might not have internet connection") + return@launchWhenCreated + } catch (e: HttpException) { + Log.e(TAG, "HttpException, unexpected response") + return@launchWhenCreated + } + runOnUiThread { + progressBar.visibility = View.GONE + recyclerView.adapter = TrendingAdapter(response) + } + } } run() diff --git a/app/src/main/java/xyz/btcland/libretube/PipedApi.kt b/app/src/main/java/xyz/btcland/libretube/PipedApi.kt new file mode 100644 index 000000000..939a58a6f --- /dev/null +++ b/app/src/main/java/xyz/btcland/libretube/PipedApi.kt @@ -0,0 +1,15 @@ +package xyz.btcland.libretube + +import retrofit2.http.GET +import retrofit2.http.Path +import retrofit2.http.Query +import xyz.btcland.libretube.obj.StreamItem +import xyz.btcland.libretube.obj.Streams + +interface PipedApi { + @GET("trending") + suspend fun getTrending(@Query("region") region: String): List + + @GET("streams/{videoId}") + suspend fun getStreams(@Path("videoId") videoId: String): Streams +} \ No newline at end of file diff --git a/app/src/main/java/xyz/btcland/libretube/Player.kt b/app/src/main/java/xyz/btcland/libretube/Player.kt index 8fdd8ec6b..405793cbf 100644 --- a/app/src/main/java/xyz/btcland/libretube/Player.kt +++ b/app/src/main/java/xyz/btcland/libretube/Player.kt @@ -6,216 +6,20 @@ import android.content.DialogInterface import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle -import android.view.View -import android.widget.ImageButton -import android.widget.TextView -import androidx.appcompat.app.AlertDialog -import androidx.core.net.toUri -import com.google.android.exoplayer2.ExoPlayer -import com.google.android.exoplayer2.MediaItem -import com.google.android.exoplayer2.source.DefaultMediaSourceFactory -import com.google.android.exoplayer2.source.MediaSource -import com.google.android.exoplayer2.source.MergingMediaSource -import com.google.android.exoplayer2.source.ProgressiveMediaSource -import com.google.android.exoplayer2.ui.StyledPlayerView -import com.google.android.exoplayer2.upstream.DataSource -import com.google.android.exoplayer2.upstream.DefaultHttpDataSource -import com.google.gson.GsonBuilder -import okhttp3.* -import java.io.IOException + class Player : Activity() { - private lateinit var exoPlayerView: StyledPlayerView - private lateinit var motionLayout: SingleViewTouchableMotionLayout - private lateinit var exoPlayer: ExoPlayer - private var videoId: String? =null - private var seekTo: Long? = 0 - private var whichQuality: Int? = 0 + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_player) - seekTo = intent.getStringExtra("seekTo")?.toLong() - whichQuality = intent.getStringExtra("quality")?.toInt() - videoId=intent.getStringExtra("videoId") - exoPlayerView = findViewById(R.id.fullscreen_player) - fetchJson(this) - } - - - - private fun fetchJson(context: Context) { - val client = OkHttpClient() - - fun run() { - val request = Request.Builder() - .url("https://pipedapi.kavin.rocks/streams/$videoId") - .build() - client.newCall(request).enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - e.printStackTrace() - } - override fun onResponse(call: Call, response: Response) { - response.use { - if (!response.isSuccessful) throw IOException("Unexpected code $response") - val body = response.body!!.string() - println(body) - val gson = GsonBuilder().create() - val videoInPlayer = gson.fromJson(body, VideoInPlayer::class.java) - var videosNameArray: Array = arrayOf() - videosNameArray += "HLS" - for (vids in videoInPlayer.videoStreams){ - val name = vids.quality +" "+ vids.format - videosNameArray += name - } - runOnUiThread { - exoPlayer = ExoPlayer.Builder(context) - .build() - var subtitle = mutableListOf() - if(videoInPlayer.subtitles.isNotEmpty()){ - subtitle?.add( - MediaItem.SubtitleConfiguration.Builder(videoInPlayer.subtitles[0].url.toUri()) - .setMimeType(videoInPlayer.subtitles[0].mimeType) // The correct MIME type (required). - .setLanguage(videoInPlayer.subtitles[0].code) // The subtitle language (optional). - .build())} - if(whichQuality==0){ - val mediaItem: MediaItem = MediaItem.Builder() - .setUri(videoInPlayer.hls) - .setSubtitleConfigurations(subtitle) - .build() - exoPlayer.setMediaItem(mediaItem) - }else{ - val dataSourceFactory: DataSource.Factory = - DefaultHttpDataSource.Factory() - val videoItem: MediaItem = MediaItem.Builder() - .setUri(videoInPlayer.videoStreams[whichQuality!!-1].url) - .setSubtitleConfigurations(subtitle) - .build() - val videoSource: MediaSource = DefaultMediaSourceFactory(dataSourceFactory) - .createMediaSource(videoItem) - var audioSource: MediaSource = DefaultMediaSourceFactory(dataSourceFactory) - .createMediaSource( - MediaItem.fromUri( - videoInPlayer.audioStreams[0].url - ) - ) - if (videoInPlayer.videoStreams[whichQuality!!-1].quality=="720p" || videoInPlayer.videoStreams[whichQuality!!-1].quality=="1080p" || videoInPlayer.videoStreams[whichQuality!!-1].quality=="480p" ){ - audioSource = ProgressiveMediaSource.Factory(dataSourceFactory) - .createMediaSource( - MediaItem.fromUri( - videoInPlayer.audioStreams[getMostBitRate( - videoInPlayer.audioStreams - )].url - ) - ) - //println("fuckkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkitttttttttttttttttttttt") - } - val mergeSource: MediaSource = MergingMediaSource(videoSource,audioSource) - exoPlayer.setMediaSource(mergeSource) - } - findViewById(R.id.quality_text).text=videosNameArray[whichQuality!!] - - exoPlayerView.setShowSubtitleButton(true) - exoPlayerView.setShowNextButton(false) - exoPlayerView.setShowPreviousButton(false) - exoPlayerView.controllerShowTimeoutMs = 1500 - exoPlayerView.controllerHideOnTouch = true - exoPlayerView.player = exoPlayer - - ///exoPlayer.getMediaItemAt(5) - exoPlayer.prepare() - exoPlayer.play() - exoPlayer.seekTo(seekTo!!) - findViewById(R.id.quality_select).setOnClickListener{ - val builder: AlertDialog.Builder? = let { - AlertDialog.Builder(context) - } - builder!!.setTitle(R.string.choose_quality_dialog) - .setItems(videosNameArray, - DialogInterface.OnClickListener { _, which -> - // The 'which' argument contains the index position - // of the selected item - //println(which) - if(videoInPlayer.subtitles.isNotEmpty()) { - var subtitle = - mutableListOf() - subtitle?.add( - MediaItem.SubtitleConfiguration.Builder(videoInPlayer.subtitles[0].url.toUri()) - .setMimeType(videoInPlayer.subtitles[0].mimeType) // The correct MIME type (required). - .setLanguage(videoInPlayer.subtitles[0].code) // The subtitle language (optional). - .build() - ) - } - if(which==0){ - val mediaItem: MediaItem = MediaItem.Builder() - .setUri(videoInPlayer.hls) - .setSubtitleConfigurations(subtitle) - .build() - exoPlayer.setMediaItem(mediaItem) - }else{ - val dataSourceFactory: DataSource.Factory = - DefaultHttpDataSource.Factory() - val videoItem: MediaItem = MediaItem.Builder() - .setUri(videoInPlayer.videoStreams[which-1].url) - .setSubtitleConfigurations(subtitle) - .build() - val videoSource: MediaSource = DefaultMediaSourceFactory(dataSourceFactory) - .createMediaSource(videoItem) - var audioSource: MediaSource = DefaultMediaSourceFactory(dataSourceFactory) - .createMediaSource( - MediaItem.fromUri( - videoInPlayer.audioStreams[0].url - ) - ) - if (videoInPlayer.videoStreams[which-1].quality=="720p" || videoInPlayer.videoStreams[which-1].quality=="1080p" || videoInPlayer.videoStreams[which-1].quality=="480p" ){ - audioSource = ProgressiveMediaSource.Factory(dataSourceFactory) - .createMediaSource( - MediaItem.fromUri( - videoInPlayer.audioStreams[getMostBitRate( - videoInPlayer.audioStreams - )].url - ) - ) - //println("fuckkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkitttttttttttttttttttttt") - } - val mergeSource: MediaSource = MergingMediaSource(videoSource,audioSource) - exoPlayer.setMediaSource(mergeSource) - } - findViewById(R.id.quality_text).text=videosNameArray[which] - }) - val dialog: AlertDialog? = builder?.create() - dialog?.show() - } - } - } - - - } - }) - } - run() } - fun getMostBitRate(audios: List):Int{ - var bitrate =0 - var index = 0 - for ((i, audio) in audios.withIndex()){ - val q = audio.quality.replace(" kbps","").toInt() - if (q>bitrate){ - bitrate=q - index = i - } - } - return index - } - override fun onStop() { - super.onStop() - myApp.seekTo=exoPlayer.currentPosition - exoPlayer.stop() - } } + diff --git a/app/src/main/java/xyz/btcland/libretube/PlayerFragment.kt b/app/src/main/java/xyz/btcland/libretube/PlayerFragment.kt index c80115ec0..789b58fcd 100644 --- a/app/src/main/java/xyz/btcland/libretube/PlayerFragment.kt +++ b/app/src/main/java/xyz/btcland/libretube/PlayerFragment.kt @@ -18,8 +18,7 @@ import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.ui.PlayerView import com.google.android.exoplayer2.ui.StyledPlayerControlView import com.google.android.exoplayer2.ui.StyledPlayerView -import com.google.gson.GsonBuilder -import com.google.gson.reflect.TypeToken + import okhttp3.* import java.io.IOException import kotlin.math.abs @@ -47,9 +46,11 @@ import android.widget.TextView import android.graphics.drawable.Drawable import com.google.android.exoplayer2.util.Util import android.graphics.drawable.ColorDrawable +import android.util.Log import androidx.appcompat.app.AlertDialog import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.text.PrecomputedTextCompat +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.exoplayer2.Player @@ -59,6 +60,15 @@ import com.google.android.exoplayer2.util.RepeatModeUtil import com.google.android.exoplayer2.ui.TimeBar import com.google.android.exoplayer2.ui.TimeBar.OnScrubListener +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import retrofit2.HttpException +import retrofit2.Retrofit +import retrofit2.converter.jackson.JacksonConverterFactory +import retrofit2.http.GET +import retrofit2.http.Path +import xyz.btcland.libretube.obj.PipedStream // TODO: Rename parameter arguments, choose names that match @@ -186,12 +196,13 @@ class PlayerFragment : Fragment() { true } } + //FullScreen button trigger view.findViewById(R.id.fullscreen).setOnClickListener{ //remember to hide everything when new shit added if (!isFullScreen){ - view.findViewById(R.id.scrollView2).visibility = View.GONE + /*view.findViewById(R.id.scrollView2).visibility = View.GONE view.findViewById(R.id.linLayout).visibility = View.GONE - view.findViewById(R.id.textTest).visibility = View.GONE + view.findViewById(R.id.textTest).visibility = View.GONE*/ //view.findViewById(R.id.main_container).visibility = View.GONE with(motionLayout) { getConstraintSet(R.id.start).constrainHeight(R.id.player, -1) @@ -200,9 +211,9 @@ class PlayerFragment : Fragment() { isFullScreen=true }else{ - view.findViewById(R.id.scrollView2).visibility = View.VISIBLE + /*view.findViewById(R.id.scrollView2).visibility = View.VISIBLE view.findViewById(R.id.linLayout).visibility = View.VISIBLE - view.findViewById(R.id.textTest).visibility = View.VISIBLE + view.findViewById(R.id.textTest).visibility = View.VISIBLE*/ //view.findViewById(R.id.main_container).visibility = View.VISIBLE with(motionLayout) { getConstraintSet(R.id.start).constrainHeight(R.id.player, 0) @@ -245,12 +256,19 @@ class PlayerFragment : Fragment() { } private fun fetchJson(view: View) { - val client = OkHttpClient() + //val client = OkHttpClient() fun run() { - val request = Request.Builder() +/* val request = Request.Builder() .url("http://piped-api.alefvanoon.xyz/streams/$videoId") .build() +*//* val retrofit = Retrofit.Builder() + .baseUrl("http://piped-api.alefvanoon.xyz/") + .addConverterFactory(JacksonConverterFactory.create()) + .build() + + val videoInPlayer2 = retrofit.create(vidVid::class.java).vidIn(videoId)*//* + client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { e.printStackTrace() @@ -264,8 +282,8 @@ class PlayerFragment : Fragment() { val videoInPlayer = gson.fromJson(body, VideoInPlayer::class.java) var videosNameArray: Array = arrayOf() videosNameArray += "HLS" - for (vids in videoInPlayer.videoStreams){ - val name = vids.quality +" "+ vids.format + for (vid in videoInPlayer.videoStreams){ + val name = vid.quality +" "+ vid.format videosNameArray += name } runOnUiThread { @@ -295,15 +313,13 @@ class PlayerFragment : Fragment() { view.findViewById(R.id.title_textView).text = videoInPlayer.title view.findViewById(R.id.quality_select).setOnClickListener{ + //Dialog for quality selection val builder: AlertDialog.Builder? = activity?.let { AlertDialog.Builder(it) } builder!!.setTitle(R.string.choose_quality_dialog) .setItems(videosNameArray, DialogInterface.OnClickListener { _, which -> - // The 'which' argument contains the index position - // of the selected item - //println(which) whichQuality = which if(videoInPlayer.subtitles.isNotEmpty()) { var subtitle = @@ -345,6 +361,7 @@ class PlayerFragment : Fragment() { val dialog: AlertDialog? = builder?.create() dialog?.show() } + //Listener for play and pause icon change exoPlayer!!.addListener(object : com.google.android.exoplayer2.Player.Listener { override fun onPlayerStateChanged(playWhenReady: Boolean,playbackState: Int) { if (playWhenReady && playbackState == Player.STATE_READY) { @@ -366,22 +383,134 @@ class PlayerFragment : Fragment() { } - }) + })*/ + + lifecycleScope.launchWhenCreated { + val response = try { + RetrofitInstance.api.getStreams(videoId!!) + }catch(e: IOException) { + println(e) + Log.e(TAG, "IOException, you might not have internet connection") + return@launchWhenCreated + } catch (e: HttpException) { + Log.e(TAG, "HttpException, unexpected response") + return@launchWhenCreated + } + var videosNameArray: Array = arrayOf() + videosNameArray += "HLS" + for (vid in response.videoStreams!!){ + val name = vid.quality +" "+ vid.format + videosNameArray += name + } + runOnUiThread { + var subtitle = mutableListOf() + if(response.subtitles!!.isNotEmpty()){ + subtitle?.add(SubtitleConfiguration.Builder(response.subtitles!![0].url!!.toUri()) + .setMimeType(response.subtitles!![0].mimeType!!) // The correct MIME type (required). + .setLanguage(response.subtitles!![0].code) // The subtitle language (optional). + .build())} + val mediaItem: MediaItem = MediaItem.Builder() + .setUri(response.hls) + .setSubtitleConfigurations(subtitle) + .build() + exoPlayer = ExoPlayer.Builder(view.context) + .build() + exoPlayerView.setShowSubtitleButton(true) + exoPlayerView.setShowNextButton(false) + exoPlayerView.setShowPreviousButton(false) + //exoPlayerView.controllerShowTimeoutMs = 1500 + exoPlayerView.controllerHideOnTouch = true + exoPlayerView.player = exoPlayer + exoPlayer.setMediaItem(mediaItem) + ///exoPlayer.getMediaItemAt(5) + exoPlayer.prepare() + exoPlayer.play() + + view.findViewById(R.id.title_textView).text = response.title + + view.findViewById(R.id.quality_select).setOnClickListener{ + //Dialog for quality selection + val builder: AlertDialog.Builder? = activity?.let { + AlertDialog.Builder(it) + } + builder!!.setTitle(R.string.choose_quality_dialog) + .setItems(videosNameArray, + DialogInterface.OnClickListener { _, which -> + whichQuality = which + if(response.subtitles!!.isNotEmpty()) { + var subtitle = + mutableListOf() + subtitle?.add( + SubtitleConfiguration.Builder(response.subtitles!![0].url!!.toUri()) + .setMimeType(response.subtitles!![0].mimeType!!) // The correct MIME type (required). + .setLanguage(response.subtitles!![0].code) // The subtitle language (optional). + .build() + ) + } + if(which==0){ + val mediaItem: MediaItem = MediaItem.Builder() + .setUri(response.hls) + .setSubtitleConfigurations(subtitle) + .build() + exoPlayer.setMediaItem(mediaItem) + }else{ + val dataSourceFactory: DataSource.Factory = + DefaultHttpDataSource.Factory() + val videoItem: MediaItem = MediaItem.Builder() + .setUri(response.videoStreams[which-1].url) + .setSubtitleConfigurations(subtitle) + .build() + val videoSource: MediaSource = DefaultMediaSourceFactory(dataSourceFactory) + .createMediaSource(videoItem) + var audioSource: MediaSource = DefaultMediaSourceFactory(dataSourceFactory) + .createMediaSource(fromUri(response.audioStreams!![0].url!!)) + if (response.videoStreams[which-1].quality=="720p" || response.videoStreams[which-1].quality=="1080p" || response.videoStreams[which-1].quality=="480p" ){ + audioSource = ProgressiveMediaSource.Factory(dataSourceFactory) + .createMediaSource(fromUri(response.audioStreams!![getMostBitRate(response.audioStreams)].url!!)) + } + val mergeSource: MediaSource = MergingMediaSource(videoSource,audioSource) + exoPlayer.setMediaSource(mergeSource) + } + view.findViewById(R.id.quality_text).text=videosNameArray[which] + }) + val dialog: AlertDialog? = builder?.create() + dialog?.show() + } + //Listener for play and pause icon change + exoPlayer!!.addListener(object : com.google.android.exoplayer2.Player.Listener { + override fun onPlayerStateChanged(playWhenReady: Boolean,playbackState: Int) { + if (playWhenReady && playbackState == Player.STATE_READY) { + // media actually playing + view.findViewById(R.id.play_imageView).setImageResource(R.drawable.ic_pause) + } else if (playWhenReady) { + // might be idle (plays after prepare()), + // buffering (plays when data available) + // or ended (plays when seek away from end) + view.findViewById(R.id.play_imageView).setImageResource(R.drawable.ic_play) + } else { + // player paused in any state + view.findViewById(R.id.play_imageView).setImageResource(R.drawable.ic_play) + } + } + }) + } + } + } run() } - fun Fragment?.runOnUiThread(action: () -> Unit) { + private fun Fragment?.runOnUiThread(action: () -> Unit) { this ?: return if (!isAdded) return // Fragment not attached to an Activity activity?.runOnUiThread(action) } - fun getMostBitRate(audios: List):Int{ + fun getMostBitRate(audios: List):Int{ var bitrate =0 var index = 0 for ((i, audio) in audios.withIndex()){ - val q = audio.quality.replace(" kbps","").toInt() + val q = audio.quality!!.replace(" kbps","").toInt() if (q>bitrate){ bitrate=q index = i diff --git a/app/src/main/java/xyz/btcland/libretube/RetrofitInstance.kt b/app/src/main/java/xyz/btcland/libretube/RetrofitInstance.kt new file mode 100644 index 000000000..791ef9199 --- /dev/null +++ b/app/src/main/java/xyz/btcland/libretube/RetrofitInstance.kt @@ -0,0 +1,14 @@ +package xyz.btcland.libretube + +import retrofit2.Retrofit +import retrofit2.converter.jackson.JacksonConverterFactory + +object RetrofitInstance { + val api: PipedApi by lazy { + Retrofit.Builder() + .baseUrl("https://piped-api.alefvanoon.xyz/") + .addConverterFactory(JacksonConverterFactory.create()) + .build() + .create(PipedApi::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/btcland/libretube/TrendingAdapter.kt b/app/src/main/java/xyz/btcland/libretube/TrendingAdapter.kt index 07137484b..764a602d3 100644 --- a/app/src/main/java/xyz/btcland/libretube/TrendingAdapter.kt +++ b/app/src/main/java/xyz/btcland/libretube/TrendingAdapter.kt @@ -10,10 +10,11 @@ import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.RecyclerView import com.squareup.picasso.Picasso +import xyz.btcland.libretube.obj.StreamItem import java.math.BigDecimal import java.math.RoundingMode -class TrendingAdapter(private val videoFeed: List