Skip to content

Commit

Permalink
Merge branch 'refs/heads/dev'
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
  • Loading branch information
PierfrancescoSoffritti committed Sep 25, 2024
2 parents 54ae0fd + 363c013 commit e5e0707
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 35 deletions.
28 changes: 21 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[<img src='./images/banner.png' alt="banner"/>](https://playstorereply.com)
#### \<Advertisement\>

:arrow_right: Check out [PlayStoreReply](https://playstorereply.com): reply to Google Play reviews using AI.
<br/>
#### [:mega: Reply to Google Play Reviews using AI :arrow_right:](https://playstorereply.com)
Increase your apps ratings. Engage with all users, no more unanswered reviews.
Save time and increase customer satisfaction.

#### \</Advertisement\>

# android-youtube-player

[![Build Status](https://travis-ci.com/PierfrancescoSoffritti/android-youtube-player.svg?branch=master)](https://travis-ci.com/PierfrancescoSoffritti/android-youtube-player)
[![Android YouTube Player](https://www.appbrain.com/stats/libraries/shield/android_youtube_player.svg)](https://www.appbrain.com/stats/libraries/details/android_youtube_player/android-youtube-player)
[![android arsenal](https://img.shields.io/badge/Android%20Arsenal-android--youtube--player-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/4322)
[![website](https://img.shields.io/badge/-website-brightgreen.svg)](https://pierfrancescosoffritti.github.io/android-youtube-player/)
Expand Down Expand Up @@ -130,7 +130,7 @@ Add this to your module level `build.gradle` file.

```gradle
dependencies {
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:12.1.0'
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:12.1.1'
}
```

Expand All @@ -141,7 +141,7 @@ Add this to your module level `build.gradle` file.

```gradle
dependencies {
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:chromecast-sender:0.28'
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:chromecast-sender:0.30'
}
```

Expand Down Expand Up @@ -296,6 +296,9 @@ YouTubePlayerView.initialize(YouTubePlayerListener listener, boolean handleNetwo
```java
YouTubePlayerView.initialize(YouTubePlayerListener listener, boolean handleNetworkEvents, IFramePlayerOptions iframePlayerOptions)
```
```java
YouTubePlayerView.initialize(YouTubePlayerListener listener, boolean handleNetworkEvents, IFramePlayerOptions iframePlayerOptions, String videoId)
```
#### `initialize(YouTubePlayerListener)`
Initialize the `YouTubePlayer`. Network events are automatically handled by the player.

Expand All @@ -309,6 +312,9 @@ By passing an `IFramePlayerOptions` to the initialize method it is possible to s

All the possible parameters and values are listed [here](https://developers.google.com/youtube/player_parameters#Parameters). Not all of them are supported in this library because some don't make sense in this context. [Open an issue](https://github.com/PierfrancescoSoffritti/android-youtube-player/issues) if you need a parameter that is not currently supported.

#### `initialize(YouTubePlayerListener, boolean, IFramePlayerOptions, String)`
By passing the `videoId` the video will be loaded as soon as possible after initialization.

### IFramePlayerOptions
The `IFramePlayerOptions` is an optional argument that can be passed to `YouTubePlayerView.initialize(YouTubePlayerListener, boolean, IFramePlayerOptions)`, it can be used to set some of the parameters of the IFrame YouTubePlayer.

Expand Down Expand Up @@ -354,6 +360,14 @@ If set to 0: the player will show captions.

If set to 1: the player won't show captions.

##### `start`
This parameter causes the player to begin playing the video at the given number of seconds from the start of the video. The parameter value is a positive integer.

It works similarly to the `seekTo` method, and the `startSeconds` argument of `loadVideo` and `cueVideo`.

##### `end`
This parameter specifies the time, measured in seconds from the beginning of the video, when the player should stop playing the video. The parameter value is a positive integer.

### Full screen
The full screen button can be added to the player by using `IFramePlayerOptions`

Expand Down Expand Up @@ -714,7 +728,7 @@ This component is useful to display and control the time of the playback. It sho
You can add it to your layout programmatically or in your xml.

```xml
<com.pierfrancescosoffritti.androidyoutubeplayer.core.ui.views.YouTubePlayerSeekBar
<com.pierfrancescosoffritti.androidyoutubeplayer.core.customui.views.YouTubePlayerSeekBar
android:id="@+id/youtube_player_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down
1 change: 0 additions & 1 deletion chromecast-receiver/js/YouTubePlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ function YouTubePlayer(communicationConstants, communicationChannel) {
fs: 0,
origin: 'https://www.youtube.com',
rel: 0,
showinfo: 0,
iv_load_policy: 3
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class PlayerConstants {
}

enum class PlaybackRate {
UNKNOWN, RATE_0_25, RATE_0_5, RATE_1, RATE_1_5, RATE_2
UNKNOWN, RATE_0_25, RATE_0_5, RATE_0_75, RATE_1, RATE_1_25, RATE_1_5, RATE_1_75, RATE_2
}
}

Expand All @@ -24,8 +24,11 @@ fun PlayerConstants.PlaybackRate.toFloat(): Float {
PlayerConstants.PlaybackRate.UNKNOWN -> 1f
PlayerConstants.PlaybackRate.RATE_0_25 -> 0.25f
PlayerConstants.PlaybackRate.RATE_0_5 -> 0.5f
PlayerConstants.PlaybackRate.RATE_0_75 -> 0.75f
PlayerConstants.PlaybackRate.RATE_1 -> 1f
PlayerConstants.PlaybackRate.RATE_1_25 -> 1.25f
PlayerConstants.PlaybackRate.RATE_1_5 -> 1.5f
PlayerConstants.PlaybackRate.RATE_1_75 -> 1.75f
PlayerConstants.PlaybackRate.RATE_2 -> 2f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ class YouTubePlayerBridge(private val youTubePlayerOwner: YouTubePlayerBridgeCal

private const val RATE_0_25 = "0.25"
private const val RATE_0_5 = "0.5"
private const val RATE_0_75 = "0.75"
private const val RATE_1 = "1"
private const val RATE_1_25 = "1.25"
private const val RATE_1_5 = "1.5"
private const val RATE_1_75 = "1.75"
private const val RATE_2 = "2"

private const val ERROR_INVALID_PARAMETER_IN_REQUEST = "2"
Expand Down Expand Up @@ -182,8 +185,11 @@ class YouTubePlayerBridge(private val youTubePlayerOwner: YouTubePlayerBridgeCal
return when {
rate.equals(RATE_0_25, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_0_25
rate.equals(RATE_0_5, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_0_5
rate.equals(RATE_0_75, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_0_75
rate.equals(RATE_1, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_1
rate.equals(RATE_1_25, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_1_25
rate.equals(RATE_1_5, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_1_5
rate.equals(RATE_1_75, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_1_75
rate.equals(RATE_2, ignoreCase = true) -> PlayerConstants.PlaybackRate.RATE_2
else -> PlayerConstants.PlaybackRate.UNKNOWN
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj
private const val FS = "fs"
internal const val ORIGIN = "origin"
private const val REL = "rel"
private const val SHOW_INFO = "showinfo"
private const val IV_LOAD_POLICY = "iv_load_policy"
private const val MODEST_BRANDING = "modestbranding"
private const val CC_LOAD_POLICY = "cc_load_policy"
private const val CC_LANG_PREF = "cc_lang_pref"
private const val LIST = "list"
private const val LIST_TYPE = "listType"
private const val START = "start"
private const val END = "end"
}

private val builderOptions = JSONObject()
Expand All @@ -49,9 +49,7 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj
addInt(FS, 0)
addString(ORIGIN, "https://www.youtube.com")
addInt(REL, 0)
addInt(SHOW_INFO, 0)
addInt(IV_LOAD_POLICY, 3)
addInt(MODEST_BRANDING, 1)
addInt(CC_LOAD_POLICY, 0)
}

Expand Down Expand Up @@ -175,12 +173,32 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj
}

/**
* Controls if the YouTube logo will be displayed in the control bar or not.
* @param modestBranding If set to 1: the YouTube logo will not be displayed in the control bar.
* If set to 0: the YouTube logo will be displayed in the control bar.
* This parameter causes the player to begin playing the video at the given number of seconds from the start of the video.
* The parameter value is a positive integer.
* @param startSeconds positive integer, number of seconds to offset playback from the start of the video.
*/
fun start(startSeconds: Int): Builder {
addInt(START, startSeconds)
return this
}

/**
* This parameter specifies the time, measured in seconds from the beginning of the video, when the player should stop playing the video.
* The parameter value is a positive integer.
* @param endSeconds positive integer specifying the time, measured in seconds from the beginning of the video, when the player should stop playing the video.
*/
fun end(endSeconds: Int): Builder {
addInt(END, endSeconds)
return this
}

/**
* The modestbranding parameter is deprecated and will have no effect.
* To align with YouTube's branding requirements, the player now determines the appropriate branding treatment based on a combination of factors, including player size, other API parameters (e.g. controls), and additional signals.
* See August 15, 2023 deprecation announcement: https://developers.google.com/youtube/player_parameters#release_notes_08_15_2023
*/
@Deprecated("Deprecated and will have no effect")
fun modestBranding(modestBranding: Int): Builder {
addInt(MODEST_BRANDING, modestBranding)
return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ internal class LegacyYouTubePlayerView(
* @param handleNetworkEvents if set to true a broadcast receiver will be registered and network events will be handled automatically.
* If set to false, you should handle network events with your own broadcast receiver.
* @param playerOptions customizable options for the embedded video player, can be null.
* @param videoId optional, used to load a video right after initialization.
*/
fun initialize(
youTubePlayerListener: YouTubePlayerListener,
handleNetworkEvents: Boolean,
playerOptions: IFramePlayerOptions
playerOptions: IFramePlayerOptions,
videoId: String?
) {
if (isYouTubePlayerReady) {
throw IllegalStateException("This YouTubePlayerView has already been initialized.")
Expand All @@ -103,14 +105,23 @@ internal class LegacyYouTubePlayerView(
}

initialize = {
webViewYouTubePlayer.initialize({ it.addListener(youTubePlayerListener) }, playerOptions)
webViewYouTubePlayer.initialize({ it.addListener(youTubePlayerListener) }, playerOptions, videoId)
}

if (!handleNetworkEvents) {
initialize()
}
}

/**
* Initialize the player.
* @param playerOptions customizable options for the embedded video player.
*
* @see LegacyYouTubePlayerView.initialize
*/
fun initialize(youTubePlayerListener: YouTubePlayerListener, handleNetworkEvents: Boolean, playerOptions: IFramePlayerOptions) =
initialize(youTubePlayerListener, handleNetworkEvents, playerOptions, null)

/**
* Initialize the player.
* @param handleNetworkEvents if set to true a broadcast receiver will be registered and network events will be handled automatically.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ internal class WebViewYouTubePlayer constructor(

internal var isBackgroundPlaybackEnabled = false

internal fun initialize(initListener: (YouTubePlayer) -> Unit, playerOptions: IFramePlayerOptions?) {
internal fun initialize(initListener: (YouTubePlayer) -> Unit, playerOptions: IFramePlayerOptions?, videoId: String?) {
youTubePlayerInitListener = initListener
initWebView(playerOptions ?: IFramePlayerOptions.default)
initWebView(playerOptions ?: IFramePlayerOptions.default, videoId)
}

// create new set to avoid concurrent modifications
Expand All @@ -111,7 +111,7 @@ internal class WebViewYouTubePlayer constructor(
}

@SuppressLint("SetJavaScriptEnabled")
private fun initWebView(playerOptions: IFramePlayerOptions) {
private fun initWebView(playerOptions: IFramePlayerOptions, videoId: String?) {
settings.apply {
javaScriptEnabled = true
mediaPlaybackRequiresUserGesture = false
Expand All @@ -121,6 +121,7 @@ internal class WebViewYouTubePlayer constructor(
addJavascriptInterface(YouTubePlayerBridge(this), "YouTubePlayerBridge")

val htmlPage = readHTMLFromUTF8File(resources.openRawResource(R.raw.ayp_youtube_player))
.replace("<<injectedVideoId>>", if (videoId != null) { "'$videoId'" } else { "undefined" })
.replace("<<injectedPlayerVars>>", playerOptions.toString())

loadDataWithBaseURL(playerOptions.getOrigin(), htmlPage, "text/html", "utf-8", null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams
Expand Down Expand Up @@ -90,24 +89,36 @@ class YouTubePlayerView(
legacyTubePlayerView.initialize(
youTubePlayerListener,
handleNetworkEvents,
IFramePlayerOptions.default
IFramePlayerOptions.default,
videoId
)
}
}

// TODO: Use @JvmOverloads instead of duplicating the method. Unfortunately that will cause a breaking change.
fun initialize(youTubePlayerListener: YouTubePlayerListener, handleNetworkEvents: Boolean, playerOptions: IFramePlayerOptions, videoId: String?) {
if (enableAutomaticInitialization) {
throw IllegalStateException(AUTO_INIT_ERROR)
}
else {
legacyTubePlayerView.initialize(youTubePlayerListener, handleNetworkEvents, playerOptions, videoId)
}
}

/**
* Initialize the player. You must call this method before using the player.
* @param youTubePlayerListener listener for player events
* @param handleNetworkEvents if set to true a broadcast receiver will be registered and network events will be handled automatically.
* If set to false, you should handle network events with your own broadcast receiver.
* @param playerOptions customizable options for the embedded video player.
* @param videoId optional, used to load an initial video.
*/
fun initialize(youTubePlayerListener: YouTubePlayerListener, handleNetworkEvents: Boolean, playerOptions: IFramePlayerOptions) {
if (enableAutomaticInitialization) {
throw IllegalStateException(AUTO_INIT_ERROR)
}
else {
legacyTubePlayerView.initialize(youTubePlayerListener, handleNetworkEvents, playerOptions)
legacyTubePlayerView.initialize(youTubePlayerListener, handleNetworkEvents, playerOptions, null)
}
}

Expand Down
1 change: 1 addition & 0 deletions core/src/main/res/raw/ayp_youtube_player.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

height: '100%',
width: '100%',
videoId: <<injectedVideoId>>,

events: {
onReady: function(event) { YouTubePlayerBridge.sendReady() },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#This is the verification token for the com.pierfrancescosoffritti.androidyoutubeplayer:core SDK.
#Tue Sep 24 22:28:45 PDT 2024
token=RLCF53RSTNFKXKRKVCHR7GH2LM
20 changes: 10 additions & 10 deletions dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
ext.versions = [
// Project
minSdk : 17,
compileSdk : 33,
compileSdk : 34,

publishVersion_core : '12.1.0',
publishVersionCode_core : 20,
publishVersion_core : '12.1.1',
publishVersionCode_core : 21,

publishVersion_chromecast : '0.29',
publishVersionCode_chromecast : 14,
publishVersion_chromecast : '0.30',
publishVersionCode_chromecast : 15,

// Plugins
gradlePlugin : '8.1.0',
gradlePlugin : '8.1.3',
dexCount : '4.0.0',
gradleNexus : '1.3.0',
dokka : '1.8.10',
Expand All @@ -19,16 +19,16 @@ ext.versions = [
kotlin : '1.8.0',

// AndroidX
androidxCore : '1.9.0',
androidxCore : '1.12.0',
appcompat : '1.6.1',
androidxAnnotations : '1.6.0',
androidxConstraintLayout : '2.1.4',
androidxRecyclerView : '1.3.0',
androidxMediarouter : '1.3.1',
androidxRecyclerView : '1.3.2',
androidxMediarouter : '1.6.0',
androidxLifecycleRuntime : '2.6.0',

// Google Play
googlePlayServicesCastFramework : '21.2.0',
googlePlayServicesCastFramework : '21.3.0',

// psoffritti
sampleAppTemplate : '1.0.3',
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
Expand Down

0 comments on commit e5e0707

Please sign in to comment.