diff --git a/app/src/main/java/com/github/libretube/BackgroundMode.kt b/app/src/main/java/com/github/libretube/BackgroundMode.kt index 3f51ea58b..ebd851e01 100644 --- a/app/src/main/java/com/github/libretube/BackgroundMode.kt +++ b/app/src/main/java/com/github/libretube/BackgroundMode.kt @@ -11,7 +11,6 @@ import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector import com.google.android.exoplayer2.ui.PlayerNotificationManager -import gen._base._base_java__rjava_resources.srcjar.R.id.title import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -45,14 +44,16 @@ class BackgroundMode { */ private lateinit var playerNotification: PlayerNotificationManager + /** + * The [AudioAttributes] handle the audio focus of the [player] + */ + private lateinit var audioAttributes: AudioAttributes + /** * Initializes the [player] with the [MediaItem]. */ private fun initializePlayer(c: Context) { - /** - * The [audioAttributes] handle the audio focus of the [player] - */ - val audioAttributes = AudioAttributes.Builder() + audioAttributes = AudioAttributes.Builder() .setUsage(C.USAGE_MEDIA) .setContentType(C.CONTENT_TYPE_MUSIC) .build() @@ -68,12 +69,16 @@ class BackgroundMode { /** * Initializes the [playerNotification] attached to the [player] and shows it. */ - private fun initializePlayerNotification(c: Context, streams: Streams) { + private fun initializePlayerNotification(c: Context) { playerNotification = PlayerNotificationManager .Builder(c, 1, "background_mode") // set the description of the notification .setMediaDescriptionAdapter( - DescriptionAdapter(streams.title!!, streams.uploader!!, streams.thumbnailUrl!!) + DescriptionAdapter( + response?.title!!, + response?.uploader!!, + response?.thumbnailUrl!! + ) ) .build() playerNotification.apply { @@ -113,7 +118,7 @@ class BackgroundMode { job.join() initializePlayer(c) - initializePlayerNotification(c, response!!) + initializePlayerNotification(c) player?.apply { playWhenReady = playWhenReadyPlayer diff --git a/app/src/main/java/com/github/libretube/Constants.kt b/app/src/main/java/com/github/libretube/Constants.kt new file mode 100644 index 000000000..521bc3a7c --- /dev/null +++ b/app/src/main/java/com/github/libretube/Constants.kt @@ -0,0 +1,7 @@ +package com.github.libretube + +const val GITHUB_API_URL = "https://api.github.com/repos/libre-tube/LibreTube/releases/latest" +const val WEBSITE_URL = "https://libre-tube.github.io/" +const val AUTHORS_URL = "https://github.com/libre-tube/LibreTube/graphs/contributors" +const val DONATE_URL = "https://libre-tube.github.io/#donate" +const val CONTRIBUTING_URL = "https://github.com/libre-tube/LibreTube#donate" diff --git a/app/src/main/java/com/github/libretube/adapters/ChaptersAdapter.kt b/app/src/main/java/com/github/libretube/adapters/ChaptersAdapter.kt index 66a0d7247..4f625c3aa 100644 --- a/app/src/main/java/com/github/libretube/adapters/ChaptersAdapter.kt +++ b/app/src/main/java/com/github/libretube/adapters/ChaptersAdapter.kt @@ -32,7 +32,7 @@ class ChaptersAdapter( chapterTitle.text = chapter.title holder.v.setOnClickListener { - val chapterStart = chapter.start!!.toLong() * 1000 // multiply by thousand for ms -> s + val chapterStart = chapter.start!!.toLong() * 1000 // s -> ms exoPlayer.seekTo(chapterStart) } } diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index 28d552abb..4c275471d 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -828,6 +828,10 @@ class PlayerFragment : Fragment() { } private fun createExoPlayer(view: View) { + val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) + val playbackSpeed = sharedPreferences.getString("playback_speed", "1F")?.toFloat() + val bufferingGoal = sharedPreferences.getString("buffering_goal", "50")?.toInt()!! + val cronetEngine: CronetEngine = CronetHelper.getCronetEngine() val cronetDataSourceFactory: CronetDataSource.Factory = CronetDataSource.Factory(cronetEngine, Executors.newCachedThreadPool()) @@ -847,6 +851,12 @@ class PlayerFragment : Fragment() { val loadControl = DefaultLoadControl.Builder() // cache the last three minutes .setBackBuffer(1000 * 60 * 3, true) + .setBufferDurationsMs( + DefaultLoadControl.DEFAULT_MIN_BUFFER_MS, + bufferingGoal * 1000, // buffering goal, s -> ms + DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS, + DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS + ) .build() exoPlayer = ExoPlayer.Builder(view.context) @@ -858,8 +868,6 @@ class PlayerFragment : Fragment() { exoPlayer.setAudioAttributes(audioAttributes, true) - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - val playbackSpeed = sharedPreferences.getString("playback_speed", "1F")?.toFloat() exoPlayer.setPlaybackSpeed(playbackSpeed!!) } diff --git a/app/src/main/java/com/github/libretube/obj/UpdateInfo.kt b/app/src/main/java/com/github/libretube/obj/UpdateInfo.kt new file mode 100644 index 000000000..91808912b --- /dev/null +++ b/app/src/main/java/com/github/libretube/obj/UpdateInfo.kt @@ -0,0 +1,7 @@ +package com.github.libretube.obj + +// data class for the update info, required to return the data +data class UpdateInfo( + val updateUrl: String, + val tagName: String +) diff --git a/app/src/main/java/com/github/libretube/preferences/AboutFragment.kt b/app/src/main/java/com/github/libretube/preferences/AboutFragment.kt index 851c6a12a..e04676f48 100644 --- a/app/src/main/java/com/github/libretube/preferences/AboutFragment.kt +++ b/app/src/main/java/com/github/libretube/preferences/AboutFragment.kt @@ -11,8 +11,12 @@ import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView import androidx.fragment.app.Fragment +import com.github.libretube.AUTHORS_URL import com.github.libretube.BuildConfig +import com.github.libretube.CONTRIBUTING_URL +import com.github.libretube.DONATE_URL import com.github.libretube.R +import com.github.libretube.WEBSITE_URL import com.google.android.material.dialog.MaterialAlertDialogBuilder class AboutFragment : Fragment() { @@ -34,19 +38,19 @@ class AboutFragment : Fragment() { val website = view.findViewById(R.id.website) website.setOnClickListener { - openLinkFromHref("https://libre-tube.github.io/") + openLinkFromHref(WEBSITE_URL) } val authors = view.findViewById(R.id.authors) authors.setOnClickListener { - openLinkFromHref("https://github.com/libre-tube/LibreTube/graphs/contributors") + openLinkFromHref(AUTHORS_URL) } val donate = view.findViewById(R.id.donate) donate.setOnClickListener { - openLinkFromHref("https://libre-tube.github.io/#donate") + openLinkFromHref(DONATE_URL) } val contributing = view.findViewById(R.id.contributing) contributing.setOnClickListener { - openLinkFromHref("https://github.com/libre-tube/LibreTube") + openLinkFromHref(CONTRIBUTING_URL) } val license = view.findViewById(R.id.license) license.setOnClickListener { diff --git a/app/src/main/java/com/github/libretube/util/DescriptionAdapter.kt b/app/src/main/java/com/github/libretube/util/DescriptionAdapter.kt index bd9de4aea..25ed99fbb 100644 --- a/app/src/main/java/com/github/libretube/util/DescriptionAdapter.kt +++ b/app/src/main/java/com/github/libretube/util/DescriptionAdapter.kt @@ -7,7 +7,10 @@ import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.ui.PlayerNotificationManager import java.net.URL -// used to show title and thumbnail of the video in the notification +/** + * The [DescriptionAdapter] is used to show title, uploaderName and thumbnail of the video in the notification + * Basic example [here](https://github.com/AnthonyMarkD/AudioPlayerSampleTest) + */ class DescriptionAdapter( private val title: String, private val channelName: String, diff --git a/app/src/main/java/com/github/libretube/util/UpdateChecker.kt b/app/src/main/java/com/github/libretube/util/UpdateChecker.kt index 554cef26c..2c6b9dada 100644 --- a/app/src/main/java/com/github/libretube/util/UpdateChecker.kt +++ b/app/src/main/java/com/github/libretube/util/UpdateChecker.kt @@ -3,8 +3,10 @@ package com.github.libretube.util import android.util.Log import androidx.fragment.app.FragmentManager import com.github.libretube.BuildConfig +import com.github.libretube.GITHUB_API_URL import com.github.libretube.dialogs.NoUpdateAvailableDialog import com.github.libretube.dialogs.UpdateAvailableDialog +import com.github.libretube.obj.UpdateInfo import java.io.BufferedReader import java.io.InputStreamReader import java.net.URL @@ -40,7 +42,7 @@ fun checkUpdate(childFragmentManager: FragmentManager) { } fun getUpdateInfo(): UpdateInfo? { - val latest = URL("https://api.github.com/repos/libre-tube/LibreTube/releases/latest") + val latest = URL(GITHUB_API_URL) val json = StringBuilder() val urlConnection: HttpsURLConnection? urlConnection = latest.openConnection() as HttpsURLConnection @@ -49,7 +51,7 @@ fun getUpdateInfo(): UpdateInfo? { var line: String? while (br.readLine().also { line = it } != null) json.append(line) - // Parse and return json data + // Parse and return the json data val jsonRoot = JSONObject(json.toString()) if (jsonRoot.has("tag_name") && jsonRoot.has("html_url") && @@ -63,7 +65,7 @@ fun getUpdateInfo(): UpdateInfo? { val name = jsonAsset.getString("name") if (name.endsWith(".apk")) { val tagName = jsonRoot.getString("name") - Log.i("", "Lastest version: $tagName") + Log.i("", "Latest version: $tagName") return UpdateInfo(updateUrl, tagName) } } @@ -71,9 +73,3 @@ fun getUpdateInfo(): UpdateInfo? { } return null } - -// data class for the update info, required to return the data -data class UpdateInfo( - val updateUrl: String, - val tagName: String -) diff --git a/app/src/main/res/drawable/ic_timelapse.xml b/app/src/main/res/drawable/ic_timelapse.xml new file mode 100644 index 000000000..1bafc2752 --- /dev/null +++ b/app/src/main/res/drawable/ic_timelapse.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/playlist_row.xml b/app/src/main/res/layout/playlist_row.xml index b0c4e6095..cca5c2238 100644 --- a/app/src/main/res/layout/playlist_row.xml +++ b/app/src/main/res/layout/playlist_row.xml @@ -2,12 +2,12 @@ + android:background="?android:attr/selectableItemBackground"> + app:strokeWidth="0dp"> - + app:cardBackgroundColor="@color/duration_background_color" + app:cardCornerRadius="8dp" + app:cardElevation="0dp"> + + + + + android:src="@drawable/ic_delete" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:shapeAppearanceOverlay="@style/roundedImageViewRounded" /> \ No newline at end of file diff --git a/app/src/main/res/layout/trending_row.xml b/app/src/main/res/layout/trending_row.xml index 72260e2ed..c62ad6cb9 100644 --- a/app/src/main/res/layout/trending_row.xml +++ b/app/src/main/res/layout/trending_row.xml @@ -1,10 +1,10 @@ + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground"> + app:layout_constraintTop_toTopOf="parent"> + android:layout_height="match_parent" + android:src="@mipmap/ic_launcher" /> - + app:cardBackgroundColor="@color/duration_background_color" + app:cardCornerRadius="8dp" + app:cardElevation="0dp"> + + + + + @@ -45,24 +58,24 @@ android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" + android:ellipsize="end" + android:maxLines="2" android:text="Title" android:textSize="15sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="@+id/thumbnailcard" app:layout_constraintStart_toEndOf="@+id/channel_image" - app:layout_constraintTop_toBottomOf="@+id/thumbnailcard" - android:ellipsize="end" - android:maxLines="2" /> + app:layout_constraintTop_toBottomOf="@+id/thumbnailcard" /> + app:layout_constraintTop_toBottomOf="@+id/textView_title" /> + android:background="?android:attr/selectableItemBackground"> + app:strokeWidth="0dp"> - + app:cardBackgroundColor="@color/duration_background_color" + app:cardCornerRadius="8dp" + app:cardElevation="0dp"> + + + + + + android:background="?android:attr/selectableItemBackground"> + app:strokeWidth="0dp"> - + app:cardBackgroundColor="@color/duration_background_color" + app:cardCornerRadius="8dp" + app:cardElevation="0dp"> + + + + + @@ -83,9 +96,9 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="12dp" - app:layout_constraintEnd_toEndOf="parent" - android:maxLines="1" android:ellipsize="end" + android:maxLines="1" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/search_channel_image" app:layout_constraintTop_toBottomOf="@+id/search_views" /> diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 6d1c2b2f0..e1e4cfcac 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -659,4 +659,12 @@ sdcard + + 50 + 100 + 200 + 300 + 450 + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6f5686b9..70863c848 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -181,4 +181,6 @@ Show related streams to videos. Show chapters Hide chapters + Buffering goal + The amount of seconds videos get preloaded at maximum. diff --git a/app/src/main/res/xml/advanced_settings.xml b/app/src/main/res/xml/advanced_settings.xml index 87546c389..a2337d75f 100644 --- a/app/src/main/res/xml/advanced_settings.xml +++ b/app/src/main/res/xml/advanced_settings.xml @@ -22,6 +22,15 @@ app:title="@string/playback_speed" app:useSimpleSummaryProvider="true" /> + +