This commit is contained in:
zaednasr 2024-09-02 23:10:23 +02:00
parent be48f8b00b
commit e3c6df850e
No known key found for this signature in database
GPG key ID: 92B1DE23AD3D0E9E
9 changed files with 1146 additions and 87 deletions

1102
CHANGELOG.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@ def properties = new Properties()
def versionMajor = 1
def versionMinor = 7
def versionPatch = 9
def versionBuild = 1 // bump for dogfood builds, public betas, etc.
def versionBuild = 2 // bump for dogfood builds, public betas, etc.
def isBeta = false
def versionExt = ""

View file

@ -16,7 +16,6 @@ import com.deniscerri.ytdl.util.Extensions.isYoutubeChannelURL
import com.deniscerri.ytdl.util.Extensions.isYoutubeURL
import com.deniscerri.ytdl.util.FileUtil
import com.deniscerri.ytdl.util.extractors.GoogleApiUtil
import com.deniscerri.ytdl.util.extractors.IYoutubeExtractor
import com.deniscerri.ytdl.util.extractors.PipedApiUtil
import com.deniscerri.ytdl.util.extractors.newpipe.NewPipeUtil
import com.deniscerri.ytdl.util.extractors.YTDLPUtil
@ -36,16 +35,12 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
private val youtubeApiUtil = YoutubeApiUtil(context)
private val ytdlpUtil = YTDLPUtil(context)
private var youtubeExtractor: IYoutubeExtractor? = null
private var pipedUtil = PipedApiUtil(context)
private var newPipeUtil = NewPipeUtil(context)
private var newPipeUtil : NewPipeUtil? = null
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
init {
youtubeExtractor = when(YoutubeExtractors.valueOf(sharedPreferences.getString("data_fetching_extractor_youtube", "PIPED")!!)) {
YoutubeExtractors.PIPED -> PipedApiUtil(context)
YoutubeExtractors.NEWPIPE -> NewPipeUtil(context)
else -> null
if (sharedPreferences.getString("youtube_data_fetching_extractor", "NEWPIPE") == "NEWPIPE") {
newPipeUtil = NewPipeUtil(context)
}
}
@ -57,12 +52,6 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
YT_DLP
}
enum class YoutubeExtractors {
YT_DLP,
PIPED,
NEWPIPE
}
suspend fun insert(it: ResultItem){
resultDao.insert(it)
}
@ -76,7 +65,7 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
val items = if (sharedPreferences.getString("api_key", "")!!.isNotBlank()) {
youtubeApiUtil.getTrending()
}else{
youtubeExtractor?.getTrending() ?: listOf()
newPipeUtil?.getTrending() ?: listOf()
}
itemCount.value = items.size
@ -88,7 +77,7 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
}
fun getStreamingUrlAndChapters(url: String) : Pair<List<String>, List<ChapterItem>?> {
val extractorsTrial = youtubeExtractor?.getStreamingUrlAndChapters(url) ?: Result.failure(Throwable())
val extractorsTrial = newPipeUtil?.getStreamingUrlAndChapters(url) ?: Result.failure(Throwable())
if (extractorsTrial.isFailure){
val res = ytdlpUtil.getStreamingUrlAndChapters(url)
return res.getOrDefault(Pair(listOf(""), null))
@ -100,8 +89,8 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
suspend fun search(inputQuery: String, resetResults: Boolean, addToResults: Boolean) : ArrayList<ResultItem>{
if (resetResults) deleteAll()
val res = when(sharedPreferences.getString("search_engine", "ytsearch")) {
"ytsearch" -> youtubeExtractor?.search(inputQuery)
"ytsearchmusic" -> youtubeExtractor?.searchMusic(inputQuery)
"ytsearch" -> newPipeUtil?.search(inputQuery)
"ytsearchmusic" -> newPipeUtil?.searchMusic(inputQuery)
else -> Result.failure(Throwable())
}
@ -124,7 +113,7 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
private suspend fun getYoutubeVideo(inputQuery: String, resetResults: Boolean, addToResults: Boolean) : List<ResultItem>{
val theURL = inputQuery.replace("\\?list.*".toRegex(), "")
val ytExtractorRes = youtubeExtractor?.getVideoData(theURL)
val ytExtractorRes = newPipeUtil?.getVideoData(theURL)
val res = if (ytExtractorRes?.isSuccess == true) {
ytExtractorRes.getOrNull()!!
@ -152,7 +141,7 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
val playlistURL = "https://youtube.com/playlist?list=${id}"
if (resetResults) deleteAll()
val items = mutableListOf<ResultItem>()
val ytExtractorResult = youtubeExtractor?.getPlaylistData(playlistURL) {
val ytExtractorResult = newPipeUtil?.getPlaylistData(playlistURL) {
if (addToResults){
runBlocking {
val ids = resultDao.insertMultiple(it)
@ -182,7 +171,7 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
private suspend fun getYoutubeChannel(url: String, resetResults: Boolean, addToResults: Boolean) : List<ResultItem>{
if (resetResults) deleteAll()
val items = mutableListOf<ResultItem>()
val ytExtractorResult = youtubeExtractor?.getChannelData(url) {
val ytExtractorResult = newPipeUtil?.getChannelData(url) {
if (addToResults){
runBlocking {
val ids = resultDao.insertMultiple(it)
@ -232,16 +221,8 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
val formatSource = source ?: sharedPreferences.getString("formats_source", "yt-dlp")
val res = if (url.isYoutubeURL()) {
when(formatSource) {
"piped" -> {
val tmpRes = pipedUtil.getFormats(url)
if (tmpRes.isFailure && source != null) {
Result.success(listOf())
}else{
tmpRes
}
}
"newpipe" -> {
val tmpRes = newPipeUtil.getFormats(url)
val tmpRes = NewPipeUtil(context).getFormats(url)
if (tmpRes.isFailure && source != null) {
Result.success(listOf())
}else{
@ -266,23 +247,17 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
val allYoutubeLinks = urls.all { it.isYoutubeURL() }
val res = when(formatSource) {
"piped" -> {
"newpipe" -> {
if (!allYoutubeLinks) {
Result.failure(Throwable())
}else{
val res = pipedUtil.getFormatsForAll(urls) {
val res = NewPipeUtil(context).getFormatsForAll(urls) {
progress(it)
}
res
}
}
"newpipe" -> {
val res = newPipeUtil.getFormatsForAll(urls) {
progress(it)
}
res
}
else -> {
Result.failure(Throwable())
}

View file

@ -1,18 +0,0 @@
package com.deniscerri.ytdl.util.extractors
import com.deniscerri.ytdl.database.models.ChapterItem
import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
interface IYoutubeExtractor {
fun getVideoData(url: String) : Result<List<ResultItem>>
fun getFormats(url: String) : Result<List<Format>>
fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>>
fun search(query: String) : Result<ArrayList<ResultItem>>
fun searchMusic(query: String) : Result<ArrayList<ResultItem>>
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>>
suspend fun getPlaylistData(id: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>>
fun getTrending() : ArrayList<ResultItem>
fun getChannelData(url: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>>
}

View file

@ -15,11 +15,10 @@ import com.yausername.youtubedl_android.YoutubeDLException
import kotlinx.coroutines.delay
import org.json.JSONException
import org.json.JSONObject
import java.util.ArrayList
import java.util.Locale
import kotlin.coroutines.cancellation.CancellationException
class PipedApiUtil(context: Context) : IYoutubeExtractor {
class PipedApiUtil(context: Context) {
private var sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private val countryCode = sharedPreferences.getString("locale", "")!!.ifEmpty { "US" }
private val defaultPipedURL = "https://pipedapi.kavin.rocks/"
@ -38,7 +37,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
return listOf()
}
override fun getVideoData(url : String) : Result<List<ResultItem>> {
fun getVideoData(url : String) : Result<List<ResultItem>> {
val id = getIDFromYoutubeURL(url)
val res = NetworkUtil.genericRequest("$pipedURL/streams/$id")
if (res.length() == 0) {
@ -49,7 +48,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
return Result.success(listOf(vid))
}
override fun getFormats(url: String) : Result<List<Format> > {
fun getFormats(url: String) : Result<List<Format> > {
try {
val id = getIDFromYoutubeURL(url)
val res = NetworkUtil.genericRequest("$pipedURL/streams/$id")
@ -67,7 +66,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
}
}
override fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>> {
fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>> {
return kotlin.runCatching {
val formatCollection = mutableListOf<MutableList<Format>>()
urls.forEach { url ->
@ -88,7 +87,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
}
@Throws(JSONException::class)
override fun search(query: String): Result<ArrayList<ResultItem>> {
fun search(query: String): Result<ArrayList<ResultItem>> {
val items = arrayListOf<ResultItem>()
val data = NetworkUtil.genericRequest("$pipedURL/search?q=$query&filter=videos&region=${countryCode}")
val dataArray = data.getJSONArray("items")
@ -107,7 +106,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
}
@Throws(JSONException::class)
override fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
val items = arrayListOf<ResultItem>()
val data = NetworkUtil.genericRequest("$pipedURL/search?q=$query=&filter=music_songs&region=${countryCode}")
val dataArray = data.getJSONArray("items")
@ -125,7 +124,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
return Result.success(items)
}
override fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
val id = getIDFromYoutubeURL(url)
val res = NetworkUtil.genericRequest("$pipedURL/streams/$id")
if (res.length() == 0) {
@ -140,7 +139,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
}
}
override suspend fun getPlaylistData(id: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
suspend fun getPlaylistData(id: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
val totalItems = mutableListOf<ResultItem>()
val nextPageToken = ""
var playlistName = ""
@ -194,7 +193,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
}
override fun getTrending(): ArrayList<ResultItem> {
fun getTrending(): ArrayList<ResultItem> {
val items = arrayListOf<ResultItem>()
val url = "$pipedURL/trending?region=${countryCode}"
val res = NetworkUtil.genericArrayRequest(url)
@ -209,7 +208,7 @@ class PipedApiUtil(context: Context) : IYoutubeExtractor {
return items
}
override fun getChannelData(
fun getChannelData(
url: String,
progress: (pagedResults: MutableList<ResultItem>) -> Unit
): Result<List<ResultItem>> {

View file

@ -9,7 +9,6 @@ import com.deniscerri.ytdl.database.models.Format
import com.deniscerri.ytdl.database.models.ResultItem
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
import com.deniscerri.ytdl.util.Extensions.toStringDuration
import com.deniscerri.ytdl.util.extractors.IYoutubeExtractor
import com.google.gson.Gson
import kotlinx.serialization.Serializer
import okhttp3.OkHttpClient
@ -39,7 +38,7 @@ import org.schabi.newpipe.extractor.utils.ExtractorHelper
import java.util.Locale
import kotlin.coroutines.cancellation.CancellationException
class NewPipeUtil(context: Context) : IYoutubeExtractor {
class NewPipeUtil(context: Context) {
private var sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private val countryCode = sharedPreferences.getString("locale", "")!!.ifEmpty { "US" }
private val language = sharedPreferences.getString("app_language", "")!!.ifEmpty { "en" }
@ -47,7 +46,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
NewPipe.init(NewPipeDownloaderImpl(OkHttpClient.Builder()), Localization(language, countryCode))
}
override fun getVideoData(url : String) : Result<List<ResultItem>> {
fun getVideoData(url : String) : Result<List<ResultItem>> {
try {
val streamInfo = StreamInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), url)
val vid = createVideoFromStream(streamInfo, url) ?: return Result.failure(Throwable())
@ -57,10 +56,10 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
}
override fun getFormats(url: String) : Result<List<Format> > {
fun getFormats(url: String) : Result<List<Format> > {
try {
val streamInfo = StreamInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), url)
val vid = createVideoFromStream(streamInfo, url)
val vid = createVideoFromStream(streamInfo, url, true)
return Result.success(vid!!.formats)
}catch(e: Exception) {
println(e)
@ -69,13 +68,14 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
}
override fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>> {
fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>> {
return kotlin.runCatching {
val formatCollection = mutableListOf<MutableList<Format>>()
urls.forEach { url ->
val streamInfo = StreamInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), url)
createVideoFromStream(streamInfo, url).apply {
formatCollection.add(this!!.formats)
createVideoFromStream(streamInfo, url, true).apply {
if (this!!.formats.isEmpty()) return Result.failure(Throwable())
formatCollection.add(this.formats)
progress(ResultViewModel.MultipleFormatProgress(url, this.formats))
}
}
@ -86,7 +86,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
@Throws(JSONException::class)
override fun search(query: String): Result<ArrayList<ResultItem>> {
fun search(query: String): Result<ArrayList<ResultItem>> {
try {
val items = arrayListOf<ResultItem>()
val res = SearchInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId),
@ -112,7 +112,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
@Throws(JSONException::class)
override fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
try {
val items = arrayListOf<ResultItem>()
val res = SearchInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId),
@ -136,7 +136,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
}
override fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
try {
val streamInfo = StreamInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), url)
val item = createVideoFromStream(streamInfo, url)
@ -149,7 +149,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
}
override fun getChannelData(url: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
fun getChannelData(url: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
try {
val req = ChannelInfo.getInfo(ServiceList.YouTube, url)
println(Gson().toJson(req))
@ -215,7 +215,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
}
override suspend fun getPlaylistData(playlistURL: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
suspend fun getPlaylistData(playlistURL: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
try {
val totalItems = mutableListOf<ResultItem>()
var nextPage : Page? = null
@ -262,7 +262,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
}
override fun getTrending(): ArrayList<ResultItem> {
fun getTrending(): ArrayList<ResultItem> {
try {
val items = arrayListOf<ResultItem>()
val info = KioskInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), "https://www.youtube.com/feed/trending")
@ -322,7 +322,7 @@ class NewPipeUtil(context: Context) : IYoutubeExtractor {
val formats : ArrayList<Format> = ArrayList()
if(sharedPreferences.getString("formats_source", "yt-dlp") == "piped" || ignoreFormatPreference){
if(sharedPreferences.getString("formats_source", "yt-dlp") == "newpipe" || ignoreFormatPreference){
if (stream.audioStreams.isNotEmpty()){
for (f in 0 until stream.audioStreams.size){
val it = stream.audioStreams[f]

View file

@ -235,13 +235,11 @@
</array>
<array name="formats_source">
<item>Piped</item>
<item>NewPipe</item>
<item>yt-dlp</item>
</array>
<array name="formats_source_values">
<item>piped</item>
<item>newpipe</item>
<item>yt-dlp</item>
</array>
@ -1499,7 +1497,6 @@
<string-array name="data_fetching_extractor_youtube">
<item>YT_DLP</item>
<item>NEWPIPE</item>
<item>PIPED</item>
</string-array>
</resources>

View file

@ -89,7 +89,7 @@
android:entries="@array/data_fetching_extractor_youtube"
android:entryValues="@array/data_fetching_extractor_youtube"
android:icon="@drawable/baseline_manage_search_24"
app:key="data_fetching_extractor_youtube"
app:key="youtube_data_fetching_extractor"
app:useSimpleSummaryProvider="true"
app:title="@string/data_fetching_extractor_youtube" />

View file

@ -0,0 +1,4 @@
# What's Changed
- newpipe extractor general fixes
- removed piped because its more annoying than anything, it doesnt work currently