diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 376d9f73..3efd5cc8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -449,6 +449,20 @@ + + + + + + + diff --git a/app/src/main/java/com/deniscerri/ytdl/database/models/YoutubeGeneratePoTokenItem.kt b/app/src/main/java/com/deniscerri/ytdl/database/models/YoutubeGeneratePoTokenItem.kt index fcadc5c7..2ab490ed 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/models/YoutubeGeneratePoTokenItem.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/models/YoutubeGeneratePoTokenItem.kt @@ -4,5 +4,6 @@ data class YoutubeGeneratePoTokenItem( var enabled: Boolean, var clients: MutableList, var poTokens: MutableList, - var visitorData: String + var visitorData: String, + var useVisitorData: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/CookieViewModel.kt b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/CookieViewModel.kt index 87970ed7..6a3560a9 100644 --- a/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/CookieViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdl/database/viewmodel/CookieViewModel.kt @@ -6,7 +6,6 @@ import android.content.ClipboardManager import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase.OPEN_READONLY -import android.os.Environment import android.util.Log import android.webkit.CookieManager import androidx.lifecycle.AndroidViewModel @@ -19,13 +18,10 @@ import com.deniscerri.ytdl.database.models.CookieItem import com.deniscerri.ytdl.database.repository.CookieRepository import com.deniscerri.ytdl.ui.more.WebViewActivity import com.deniscerri.ytdl.util.FileUtil -import com.google.gson.GsonBuilder import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext import java.io.File -import java.util.Calendar import java.util.Date diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/HomeFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/HomeFragment.kt index 3f835e9f..67505aaf 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/HomeFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/HomeFragment.kt @@ -45,7 +45,6 @@ import com.deniscerri.ytdl.ui.adapter.SearchSuggestionsAdapter import com.deniscerri.ytdl.ui.more.WebViewActivity import com.deniscerri.ytdl.util.Extensions.enableFastScroll import com.deniscerri.ytdl.util.Extensions.isURL -import com.deniscerri.ytdl.util.FileUtil import com.deniscerri.ytdl.util.NotificationUtil import com.deniscerri.ytdl.util.ThemeUtil import com.deniscerri.ytdl.util.UiUtil @@ -67,7 +66,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.io.File import java.net.URL import kotlin.collections.ArrayList diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt index ef5a61ca..233808da 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/downloadcard/DownloadBottomSheetDialog.kt @@ -60,7 +60,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import java.net.URL diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/CookiesFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/CookiesFragment.kt index 21baf624..c94f4a0c 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/CookiesFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/CookiesFragment.kt @@ -17,7 +17,6 @@ import android.view.inputmethod.InputMethodManager import android.widget.EditText import android.widget.RelativeLayout import android.widget.TextView -import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.core.widget.doOnTextChanged import androidx.fragment.app.Fragment @@ -45,7 +44,6 @@ import com.google.android.material.chip.Chip import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.materialswitch.MaterialSwitch import com.google.android.material.snackbar.Snackbar -import com.google.android.material.textfield.TextInputLayout import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/WebViewActivity.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/WebViewActivity.kt index 95922354..95d23fdc 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/WebViewActivity.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/WebViewActivity.kt @@ -77,6 +77,7 @@ class WebViewActivity : BaseActivity() { generateBtn = toolbar.findViewById(R.id.generate) webViewCompose = findViewById(R.id.webview_compose) cookieManager = CookieManager.getInstance() + cookieManager.removeAllCookies(null) preferences = PreferenceManager.getDefaultSharedPreferences(this@WebViewActivity) @@ -92,7 +93,6 @@ class WebViewActivity : BaseActivity() { } toolbar.setNavigationOnClickListener { - cookieManager.flush() onBackPressedDispatcher.onBackPressed() } @@ -119,7 +119,6 @@ class WebViewActivity : BaseActivity() { } } } - cookieManager.removeAllCookies(null) withContext(Dispatchers.Main) { this@WebViewActivity.setResult(RESULT_OK) this@WebViewActivity.finish() diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/AdvancedSettingsFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/AdvancedSettingsFragment.kt index ef46de50..d5fd612d 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/AdvancedSettingsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/AdvancedSettingsFragment.kt @@ -45,8 +45,7 @@ class AdvancedSettingsFragment : BaseSettingsFragment() { } findPreference("youtube_other_extractor_args")?.apply { - fun setValue() { - val pf = prefs.getString("youtube_other_extractor_args", "")!! + fun setValue(pf: String) { if (pf.length > 50) { this.summary = pf.take(50) + "..." }else { @@ -54,14 +53,11 @@ class AdvancedSettingsFragment : BaseSettingsFragment() { } } - setOnPreferenceChangeListener { preference, newValue -> - setValue() + setOnPreferenceChangeListener { _, newValue -> + setValue(newValue as String) true } - - setValue() - - + setValue(prefs.getString("youtube_other_extractor_args", "")!!) } val formatImportanceAudio: Preference? = findPreference("format_importance_audio") diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/GenerateYoutubePoTokensFragment.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt similarity index 69% rename from app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/GenerateYoutubePoTokensFragment.kt rename to app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt index 5f940a54..bb0107b5 100644 --- a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/GenerateYoutubePoTokensFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/GenerateYoutubePoTokensFragment.kt @@ -1,36 +1,37 @@ -package com.deniscerri.ytdl.ui.more.settings.advanced +package com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens +import android.app.Activity +import android.app.ActivityManager +import android.content.Context +import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView +import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager +import androidx.work.WorkManager import com.afollestad.materialdialogs.utils.MDUtil.getStringArray import com.deniscerri.ytdl.R import com.deniscerri.ytdl.database.models.YoutubeGeneratePoTokenItem import com.deniscerri.ytdl.database.models.YoutubePoTokenItem import com.deniscerri.ytdl.ui.more.settings.SettingsActivity -import com.deniscerri.ytdl.util.Extensions.getIDFromYoutubeURL +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview.PoTokenWebViewLoginActivity import com.deniscerri.ytdl.util.UiUtil -import com.deniscerri.ytdl.util.extractors.potoken.PoTokenGenerator import com.google.android.material.button.MaterialButton import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.materialswitch.MaterialSwitch import com.google.android.material.snackbar.Snackbar -import com.google.android.material.textfield.TextInputLayout import com.google.gson.Gson -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class GenerateYoutubePoTokensFragment : Fragment() { private lateinit var settingsActivity: SettingsActivity private lateinit var preferences: SharedPreferences private lateinit var configuration : MutableList + private lateinit var workManager : WorkManager private lateinit var poTokenGenerator: PoTokenGenerator private val sampleURL = "https://www.youtube.com/watch?v=aqz-KE-bpKQ" // Big Buck Bunny @@ -44,6 +45,7 @@ class GenerateYoutubePoTokensFragment : Fragment() { settingsActivity.changeTopAppbarTitle(getString(R.string.generate_potokens)) preferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) poTokenGenerator = PoTokenGenerator() + workManager = WorkManager.getInstance(requireContext()) return inflater.inflate(R.layout.fragment_generate_youtube_po_token, container, false) } @@ -59,7 +61,7 @@ class GenerateYoutubePoTokensFragment : Fragment() { private fun initWeb() { val conf = configuration.find { it.clients.any { it2 -> it2.contains("web") } } - ?: YoutubeGeneratePoTokenItem(false, mutableListOf("mweb"), mutableListOf(), "") + ?: YoutubeGeneratePoTokenItem(false, mutableListOf("mweb"), mutableListOf(), "", false) val switch = requireView().findViewById(R.id.web_client_switch) @@ -71,8 +73,10 @@ class GenerateYoutubePoTokensFragment : Fragment() { val playerClientText = requireView().findViewById(R.id.content_playerclient) val regenerate = requireView().findViewById(R.id.regenerate_webview_potokens) + val useVisitorData = requireView().findViewById(R.id.use_visitor_data) switch.isChecked = conf.enabled + useVisitorData.isEnabled = conf.enabled fun setValues(conf: YoutubeGeneratePoTokenItem) { gvs.text = conf.poTokens.find { it.context == "gvs" }?.token ?: "" @@ -121,36 +125,53 @@ class GenerateYoutubePoTokensFragment : Fragment() { .show() } - regenerate.setOnClickListener { - lifecycleScope.launch { - val res = withContext(Dispatchers.IO) { - poTokenGenerator.getWebClientPoToken(sampleURL.getIDFromYoutubeURL()) - } + val webPoTokenResultLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result -> + if (result.resultCode == Activity.RESULT_OK) { + val streamingDataPoTokenResult = result.data!!.getStringExtra("streaming_potoken") ?: "" + val playerRequestPoTokenResult = result.data!!.getStringExtra("player_potoken") ?: "" + val visitorDataResult = result.data!!.getStringExtra("visitor_data") ?: "" - if (res == null) { - Snackbar.make(requireView(), getString(R.string.network_error), Snackbar.LENGTH_LONG).show() - }else{ - configuration.remove(conf) - conf.poTokens.clear() - conf.poTokens.add(YoutubePoTokenItem("gvs", res.streamingDataPoToken ?: "")) - conf.poTokens.add(YoutubePoTokenItem("player", res.playerRequestPoToken)) - conf.visitorData = res.visitorData - configuration.add(conf) - setValues(conf) - preferences.edit().putString("youtube_generated_po_tokens", Gson().toJson(configuration).toString()).apply() - } + configuration.remove(conf) + conf.poTokens.clear() + conf.poTokens.add(YoutubePoTokenItem("gvs", streamingDataPoTokenResult)) + conf.poTokens.add(YoutubePoTokenItem("player", playerRequestPoTokenResult)) + conf.visitorData = visitorDataResult + + configuration.add(conf) + setValues(conf) + preferences.edit().putString("youtube_generated_po_tokens", Gson().toJson(configuration).toString()).apply() + }else { + Snackbar.make(requireView(), R.string.network_error, Snackbar.LENGTH_SHORT).show() } } + regenerate.setOnClickListener { + webPoTokenResultLauncher.launch(Intent(requireContext(), PoTokenWebViewLoginActivity::class.java)) + } + switch.setOnClickListener { configuration.remove(conf) conf.enabled = switch.isChecked + useVisitorData.isEnabled = switch.isChecked configuration.add(conf) preferences.edit().putString("youtube_generated_po_tokens", Gson().toJson(configuration).toString()).apply() if (conf.poTokens.isEmpty()) { regenerate.performClick() } } + + useVisitorData?.apply { + this.isChecked = conf.useVisitorData + setOnCheckedChangeListener { _, b -> + configuration.remove(conf) + conf.useVisitorData = b + configuration.add(conf) + preferences.edit().putString("youtube_generated_po_tokens", Gson().toJson(configuration).toString()).apply() + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/PoTokenGenerator.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/PoTokenGenerator.kt similarity index 96% rename from app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/PoTokenGenerator.kt rename to app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/PoTokenGenerator.kt index 3aaf84e0..22b03574 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/PoTokenGenerator.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/PoTokenGenerator.kt @@ -1,13 +1,12 @@ -package com.deniscerri.ytdl.util.extractors.potoken +package com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens import android.os.Handler import android.os.Looper import android.util.Log import android.webkit.CookieManager -import androidx.preference.PreferenceManager import com.deniscerri.ytdl.App import com.deniscerri.ytdl.BuildConfig -import com.deniscerri.ytdl.util.extractors.potoken.webview.PoTokenWebView +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview.PoTokenWebView import kotlinx.coroutines.runBlocking import org.schabi.newpipe.extractor.NewPipe import org.schabi.newpipe.extractor.services.youtube.InnertubeClientRequestInfo diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/webview/JavascriptUtil.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/JavascriptUtil.kt similarity index 97% rename from app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/webview/JavascriptUtil.kt rename to app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/JavascriptUtil.kt index 58f197d6..d5814c96 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/webview/JavascriptUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/JavascriptUtil.kt @@ -1,6 +1,5 @@ -package com.deniscerri.ytdl.util.extractors.potoken.webview +package com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview -import com.deniscerri.ytdl.util.extractors.potoken.PoTokenException import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonNull import kotlinx.serialization.json.JsonObject diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/PoTokenException.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenException.kt similarity index 81% rename from app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/PoTokenException.kt rename to app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenException.kt index 5a819929..d7d45ee2 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/PoTokenException.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenException.kt @@ -1,4 +1,4 @@ -package com.deniscerri.ytdl.util.extractors.potoken +package com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview class PoTokenException(message: String) : Exception(message) diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/webview/PoTokenWebView.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenWebView.kt similarity index 95% rename from app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/webview/PoTokenWebView.kt rename to app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenWebView.kt index 039058a2..fa88a9c6 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/potoken/webview/PoTokenWebView.kt +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenWebView.kt @@ -1,4 +1,4 @@ -package com.deniscerri.ytdl.util.extractors.potoken.webview +package com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview import android.content.Context import android.os.Build @@ -9,7 +9,6 @@ import android.webkit.WebChromeClient import android.webkit.WebView import androidx.annotation.MainThread import androidx.collection.ArrayMap -import androidx.preference.PreferenceManager import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope @@ -18,13 +17,10 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import com.deniscerri.ytdl.BuildConfig -import com.deniscerri.ytdl.util.extractors.potoken.BadWebViewException -import com.deniscerri.ytdl.util.extractors.potoken.PoTokenException -import com.deniscerri.ytdl.util.extractors.potoken.buildExceptionForJsError -import com.deniscerri.ytdl.util.extractors.potoken.webview.JavascriptUtil.parseChallengeData -import com.deniscerri.ytdl.util.extractors.potoken.webview.JavascriptUtil.parseIntegrityTokenData -import com.deniscerri.ytdl.util.extractors.potoken.webview.JavascriptUtil.stringToU8 -import com.deniscerri.ytdl.util.extractors.potoken.webview.JavascriptUtil.u8ToBase64 +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview.JavascriptUtil.parseChallengeData +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview.JavascriptUtil.parseIntegrityTokenData +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview.JavascriptUtil.stringToU8 +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview.JavascriptUtil.u8ToBase64 import okhttp3.Headers.Companion.toHeaders import okhttp3.OkHttpClient import okhttp3.RequestBody.Companion.toRequestBody diff --git a/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenWebViewLoginActivity.kt b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenWebViewLoginActivity.kt new file mode 100644 index 00000000..e2caeba1 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdl/ui/more/settings/advanced/generateyoutubepotokens/webview/PoTokenWebViewLoginActivity.kt @@ -0,0 +1,141 @@ +package com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.webview + +import android.annotation.SuppressLint +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.webkit.CookieManager +import android.webkit.WebView +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.core.view.forEach +import androidx.lifecycle.lifecycleScope +import com.deniscerri.ytdl.R +import com.deniscerri.ytdl.ui.BaseActivity +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.PoTokenGenerator +import com.google.accompanist.web.AccompanistWebChromeClient +import com.google.accompanist.web.AccompanistWebViewClient +import com.google.accompanist.web.WebView +import com.google.accompanist.web.rememberWebViewState +import com.google.android.material.appbar.AppBarLayout +import com.google.android.material.appbar.MaterialToolbar +import com.google.android.material.button.MaterialButton +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + + +class PoTokenWebViewLoginActivity : BaseActivity() { + private lateinit var webView: WebView + private lateinit var webViewCompose: ComposeView + private lateinit var toolbar: MaterialToolbar + private lateinit var generateBtn: MaterialButton + private lateinit var cookieManager: CookieManager + private lateinit var webViewClient: AccompanistWebViewClient + + private val sampleVideoID = "aqz-KE-bpKQ" //Big Buck Bunny + + @SuppressLint("SetJavaScriptEnabled") + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.webview_activity) + lifecycleScope.launch { + val appbar = findViewById(R.id.webview_appbarlayout) + toolbar = appbar.findViewById(R.id.webviewToolbar) + toolbar.menu.forEach { it.isVisible = false } + + generateBtn = toolbar.findViewById(R.id.generate) + webViewCompose = findViewById(R.id.webview_compose) + cookieManager = CookieManager.getInstance() + + webViewClient = object : AccompanistWebViewClient() { + override fun onPageFinished(view: WebView?, url: String?) { + super.onPageFinished(view, url) + kotlin.runCatching { + toolbar.title = view?.title ?: "" + } + } + } + + toolbar.setNavigationOnClickListener { + finishAndRemoveTask() + } + + generateBtn.setOnClickListener { + generateBtn.isEnabled = false + + lifecycleScope.launch { + val generator = PoTokenGenerator() + val res = withContext(Dispatchers.IO) { + generator.getWebClientPoToken(sampleVideoID) + } + + if (res == null) { + setResult(RESULT_CANCELED) + }else { + val intent = Intent() + intent.putExtra("visitor_data", res.visitorData) + intent.putExtra("player_potoken", res.playerRequestPoToken) + intent.putExtra("streaming_potoken", res.streamingDataPoToken) + setResult(RESULT_OK, intent) + } + + webView.clearCache(true) + // ensures that the WebView isn't doing anything when destroying it + webView.loadUrl("about:blank") + webView.onPause() + webView.removeAllViews() + webView.destroy() + finish() + } + } + + webViewCompose.apply { + setContent { WebViewView() } + } + } + + } + + @SuppressLint("SetJavaScriptEnabled", "JavascriptInterface") + @Composable + fun WebViewView() { + val webViewChromeClient = remember { + object : AccompanistWebChromeClient() { + } + } + + Scaffold(modifier = Modifier.fillMaxSize()) { paddingValues -> + WebView( + state = rememberWebViewState("https://youtube.com/account"), client = webViewClient, chromeClient = webViewChromeClient, + modifier = Modifier + .padding(paddingValues) + .fillMaxSize(), + captureBackPresses = false, factory = { context -> + WebView(context).apply { + webView = this + settings.run { + javaScriptEnabled = true + domStorageEnabled = true + javaScriptCanOpenWindowsAutomatically = true + if (Build.VERSION.SDK_INT >= 26) { + safeBrowsingEnabled = true + } + } + cookieManager.setAcceptThirdPartyCookies(this, true) + } + } + ) + } + } + + companion object { + const val TAG = "PoTokenWebViewActivity" + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt index a65ba246..ad992f1e 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/extractors/YTDLPUtil.kt @@ -1321,7 +1321,7 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co } } - if (dataSyncID.isBlank()) { + if (dataSyncID.isBlank() && value.useVisitorData) { extractorArgs.add("player_skip=webpage,configs") extractorArgs.add("visitor_data=${value.visitorData}") } diff --git a/app/src/main/java/com/deniscerri/ytdl/util/extractors/newpipe/NewPipeUtil.kt b/app/src/main/java/com/deniscerri/ytdl/util/extractors/newpipe/NewPipeUtil.kt index fc12d2f2..051835aa 100644 --- a/app/src/main/java/com/deniscerri/ytdl/util/extractors/newpipe/NewPipeUtil.kt +++ b/app/src/main/java/com/deniscerri/ytdl/util/extractors/newpipe/NewPipeUtil.kt @@ -10,7 +10,7 @@ import com.deniscerri.ytdl.database.models.ResultItem import com.deniscerri.ytdl.database.viewmodel.ResultViewModel import com.deniscerri.ytdl.util.Extensions.getIDFromYoutubeURL import com.deniscerri.ytdl.util.Extensions.toStringDuration -import com.deniscerri.ytdl.util.extractors.potoken.PoTokenGenerator +import com.deniscerri.ytdl.ui.more.settings.advanced.generateyoutubepotokens.PoTokenGenerator import com.google.gson.Gson import okhttp3.OkHttpClient import org.json.JSONException @@ -24,7 +24,6 @@ import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler import org.schabi.newpipe.extractor.localization.Localization import org.schabi.newpipe.extractor.playlist.PlaylistInfo import org.schabi.newpipe.extractor.search.SearchInfo -import org.schabi.newpipe.extractor.services.youtube.PoTokenResult import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory import org.schabi.newpipe.extractor.stream.StreamInfo diff --git a/app/src/main/java/com/deniscerri/ytdl/work/AutoGenerateWebPoTokenWorker.kt b/app/src/main/java/com/deniscerri/ytdl/work/AutoGenerateWebPoTokenWorker.kt new file mode 100644 index 00000000..3019f431 --- /dev/null +++ b/app/src/main/java/com/deniscerri/ytdl/work/AutoGenerateWebPoTokenWorker.kt @@ -0,0 +1,37 @@ +package com.deniscerri.ytdl.work + +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE +import android.os.Build +import android.os.Environment +import android.os.Handler +import android.os.Looper +import android.widget.Toast +import androidx.work.ForegroundInfo +import androidx.work.Worker +import androidx.work.WorkerParameters +import com.deniscerri.ytdl.App +import com.deniscerri.ytdl.MainActivity +import com.deniscerri.ytdl.R +import com.deniscerri.ytdl.util.FileUtil +import com.deniscerri.ytdl.util.NotificationUtil +import java.io.File +import java.nio.file.Files +import java.nio.file.StandardCopyOption + + +class AutoGenerateWebPoTokenWorker( + private val context: Context, + workerParams: WorkerParameters +) : Worker(context, workerParams) { + override fun doWork(): Result { + return Result.success() + } + + companion object { + const val TAG = "AutoGenerateWebPoTokenWorker" + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_generate_youtube_po_token.xml b/app/src/main/res/layout/fragment_generate_youtube_po_token.xml index 658c6ef9..0b20f81e 100644 --- a/app/src/main/res/layout/fragment_generate_youtube_po_token.xml +++ b/app/src/main/res/layout/fragment_generate_youtube_po_token.xml @@ -222,6 +222,16 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> + - + app:layout_constraintTop_toTopOf="parent" + app:liftOnScroll="false"> - + android:layout_height="?attr/actionBarSize" + app:layout_scrollFlags="scroll" + app:menu="@menu/webview_menu" + app:navigationContentDescription="@string/back" + app:navigationIcon="?attr/homeAsUpIndicator"> - +