1.7.9.1 fr
This commit is contained in:
parent
4a6b8f450d
commit
defe14f3cc
11 changed files with 160 additions and 79 deletions
|
|
@ -16,6 +16,8 @@ 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
|
||||
import com.deniscerri.ytdl.util.extractors.YoutubeApiUtil
|
||||
|
|
@ -33,12 +35,20 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
}
|
||||
|
||||
private val youtubeApiUtil = YoutubeApiUtil(context)
|
||||
//private val pipedApiUtil = PipedApiUtil(context)
|
||||
private val newPipeUtil = NewPipeUtil(context)
|
||||
private val ytdlpUtil = YTDLPUtil(context)
|
||||
|
||||
private var youtubeExtractor: IYoutubeExtractor? = null
|
||||
private var pipedUtil = PipedApiUtil(context)
|
||||
private var newPipeUtil = NewPipeUtil(context)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
enum class SourceType {
|
||||
YOUTUBE_VIDEO,
|
||||
YOUTUBE_PLAYLIST,
|
||||
|
|
@ -47,6 +57,12 @@ 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)
|
||||
}
|
||||
|
|
@ -60,7 +76,7 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
val items = if (sharedPreferences.getString("api_key", "")!!.isNotBlank()) {
|
||||
youtubeApiUtil.getTrending()
|
||||
}else{
|
||||
newPipeUtil.getTrending()
|
||||
youtubeExtractor?.getTrending() ?: listOf()
|
||||
}
|
||||
|
||||
itemCount.value = items.size
|
||||
|
|
@ -72,27 +88,27 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
}
|
||||
|
||||
fun getStreamingUrlAndChapters(url: String) : Pair<List<String>, List<ChapterItem>?> {
|
||||
val newPipeTrial = newPipeUtil.getStreamingUrlAndChapters(url)
|
||||
if (newPipeTrial.isFailure){
|
||||
val extractorsTrial = youtubeExtractor?.getStreamingUrlAndChapters(url) ?: Result.failure(Throwable())
|
||||
if (extractorsTrial.isFailure){
|
||||
val res = ytdlpUtil.getStreamingUrlAndChapters(url)
|
||||
return res.getOrDefault(Pair(listOf(""), null))
|
||||
}
|
||||
|
||||
return newPipeTrial.getOrNull()!!
|
||||
return extractorsTrial.getOrNull()!!
|
||||
}
|
||||
|
||||
suspend fun search(inputQuery: String, resetResults: Boolean, addToResults: Boolean) : ArrayList<ResultItem>{
|
||||
if (resetResults) deleteAll()
|
||||
val res = when(sharedPreferences.getString("search_engine", "ytsearch")) {
|
||||
"ytsearch" -> newPipeUtil.search(inputQuery)
|
||||
"ytsearchmusic" -> newPipeUtil.searchMusic(inputQuery)
|
||||
"ytsearch" -> youtubeExtractor?.search(inputQuery)
|
||||
"ytsearchmusic" -> youtubeExtractor?.searchMusic(inputQuery)
|
||||
else -> Result.failure(Throwable())
|
||||
}
|
||||
|
||||
val items = if (res.isSuccess) {
|
||||
val items = if (res?.isSuccess == true) {
|
||||
res.getOrNull()!!
|
||||
}else{
|
||||
//fallback if newpipe failed
|
||||
//fallback to yt-dlp
|
||||
ytdlpUtil.getFromYTDL(inputQuery)
|
||||
}
|
||||
|
||||
|
|
@ -108,10 +124,10 @@ 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 newPipeRes = newPipeUtil.getVideoData(theURL)
|
||||
val ytExtractorRes = youtubeExtractor?.getVideoData(theURL)
|
||||
|
||||
val res = if (newPipeRes.isSuccess) {
|
||||
newPipeRes.getOrNull()!!
|
||||
val res = if (ytExtractorRes?.isSuccess == true) {
|
||||
ytExtractorRes.getOrNull()!!
|
||||
}else{
|
||||
ytdlpUtil.getFromYTDL(inputQuery)
|
||||
}
|
||||
|
|
@ -136,7 +152,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 newPipeResult = newPipeUtil.getPlaylistData(playlistURL) {
|
||||
val ytExtractorResult = youtubeExtractor?.getPlaylistData(playlistURL) {
|
||||
if (addToResults){
|
||||
runBlocking {
|
||||
val ids = resultDao.insertMultiple(it)
|
||||
|
|
@ -148,8 +164,8 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
items.addAll(it)
|
||||
}
|
||||
|
||||
val response = if (newPipeResult.isSuccess){
|
||||
newPipeResult.getOrElse { items }
|
||||
val response = if (ytExtractorResult?.isSuccess == true){
|
||||
ytExtractorResult.getOrElse { items }
|
||||
}else{
|
||||
val res = ytdlpUtil.getFromYTDL(playlistURL)
|
||||
val ids = resultDao.insertMultiple(res)
|
||||
|
|
@ -166,7 +182,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 newPipeResult = newPipeUtil.getChannelData(url) {
|
||||
val ytExtractorResult = youtubeExtractor?.getChannelData(url) {
|
||||
if (addToResults){
|
||||
runBlocking {
|
||||
val ids = resultDao.insertMultiple(it)
|
||||
|
|
@ -178,8 +194,8 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
items.addAll(it)
|
||||
}
|
||||
|
||||
val response = if (newPipeResult.isSuccess){
|
||||
newPipeResult.getOrElse { items }
|
||||
val response = if (ytExtractorResult?.isSuccess == true){
|
||||
ytExtractorResult.getOrElse { items }
|
||||
}else{
|
||||
val res = ytdlpUtil.getFromYTDL(url)
|
||||
val ids = resultDao.insertMultiple(res)
|
||||
|
|
@ -214,12 +230,25 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
|
||||
fun getFormats(url: String, source : String? = null) : List<Format> {
|
||||
val formatSource = source ?: sharedPreferences.getString("formats_source", "yt-dlp")
|
||||
val res = if (url.isYoutubeURL() && formatSource == "piped") {
|
||||
val tmpRes = newPipeUtil.getFormats(url)
|
||||
if (tmpRes.isFailure && source != null) {
|
||||
Result.success(listOf())
|
||||
}else{
|
||||
tmpRes
|
||||
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)
|
||||
if (tmpRes.isFailure && source != null) {
|
||||
Result.success(listOf())
|
||||
}else{
|
||||
tmpRes
|
||||
}
|
||||
}
|
||||
else -> Result.failure(Throwable())
|
||||
}
|
||||
}else{
|
||||
Result.failure(Throwable())
|
||||
|
|
@ -235,18 +264,40 @@ class ResultRepository(private val resultDao: ResultDao, private val context: Co
|
|||
suspend fun getFormatsMultiple(urls: List<String>, source: String? = null, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : MutableList<MutableList<Format>> {
|
||||
val formatSource = source ?: sharedPreferences.getString("formats_source", "yt-dlp")
|
||||
val allYoutubeLinks = urls.all { it.isYoutubeURL() }
|
||||
if (allYoutubeLinks && formatSource == "piped") {
|
||||
val res = newPipeUtil.getFormatsForAll(urls) {
|
||||
progress(it)
|
||||
|
||||
val res = when(formatSource) {
|
||||
"piped" -> {
|
||||
if (!allYoutubeLinks) {
|
||||
Result.failure(Throwable())
|
||||
}else{
|
||||
val res = pipedUtil.getFormatsForAll(urls) {
|
||||
progress(it)
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
}
|
||||
"newpipe" -> {
|
||||
val res = newPipeUtil.getFormatsForAll(urls) {
|
||||
progress(it)
|
||||
}
|
||||
res
|
||||
}
|
||||
else -> {
|
||||
Result.failure(Throwable())
|
||||
}
|
||||
}
|
||||
|
||||
if (res.isSuccess) {
|
||||
return res.getOrElse { mutableListOf() }
|
||||
}
|
||||
else {
|
||||
val res = ytdlpUtil.getFormatsForAll(urls) {
|
||||
progress(it)
|
||||
}
|
||||
return res.getOrElse { mutableListOf() }
|
||||
|
||||
//last fallback
|
||||
val ytdlpRes = ytdlpUtil.getFormatsForAll(urls) {
|
||||
progress(it)
|
||||
}
|
||||
|
||||
return ytdlpRes.getOrElse { mutableListOf() }
|
||||
}
|
||||
|
||||
suspend fun delete(item: ResultItem){
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class ActiveDownloadAdapter(onItemClickListener: OnItemClickListener, activity:
|
|||
sideDetails.add(item.container.uppercase().ifEmpty { item.format.container.uppercase() })
|
||||
|
||||
val fileSize = FileUtil.convertFileSize(item.format.filesize)
|
||||
if (fileSize != "?") sideDetails.add(fileSize)
|
||||
if (fileSize != "?" && item.downloadSections.isBlank()) sideDetails.add(fileSize)
|
||||
formatDetailsChip.text = sideDetails.filter { it.isNotBlank() }.joinToString(" · ")
|
||||
|
||||
//OUTPUT
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class ActiveDownloadMinifiedAdapter(onItemClickListener: OnItemClickListener, ac
|
|||
|
||||
val fileSize = card.findViewById<TextView>(R.id.file_size)
|
||||
val fileSizeReadable = FileUtil.convertFileSize(item.format.filesize)
|
||||
if (fileSizeReadable == "?") fileSize.visibility = View.GONE
|
||||
if (fileSizeReadable == "?" && item.downloadSections.isNotBlank()) fileSize.visibility = View.GONE
|
||||
else fileSize.text = fileSizeReadable
|
||||
|
||||
val menu = card.findViewById<View>(R.id.options)
|
||||
|
|
|
|||
|
|
@ -1571,12 +1571,10 @@ object UiUtil {
|
|||
|
||||
|
||||
fun handleNoResults(context: Activity, message: String, continueAnyway: Boolean = false, continued: () -> Unit, closed: () -> Unit) {
|
||||
val updateYTDLP = "<span style='color:#d43c3b';>${context.getString(R.string.update_ytdl)}</span>"
|
||||
.parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
|
||||
val errDialog = MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.no_results)
|
||||
.setMessage(message + "\n\n" + updateYTDLP)
|
||||
.setMessage(message)
|
||||
|
||||
errDialog.setPositiveButton(R.string.copy_log) { d:DialogInterface?, _:Int ->
|
||||
val clipboard: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
|
|
@ -1594,23 +1592,7 @@ object UiUtil {
|
|||
closed()
|
||||
}
|
||||
|
||||
val dialog = errDialog.show()
|
||||
dialog.findViewById<View>(android.R.id.message)?.setOnClickListener {
|
||||
dialog.cancel()
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val res = UpdateUtil(context).updateYoutubeDL()
|
||||
if (res == YoutubeDL.UpdateStatus.DONE) {
|
||||
val version = YoutubeDL.getInstance().version(context)
|
||||
withContext(Dispatchers.Main){
|
||||
Toast.makeText(context, context.getString(R.string.ytld_update_success) + " [${version}]", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}else {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, context.getString(R.string.you_are_in_latest_version), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
errDialog.show()
|
||||
}
|
||||
|
||||
fun showErrorDialog(context: Context, it: String){
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
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>>
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ import java.util.ArrayList
|
|||
import java.util.Locale
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
class PipedApiUtil(private val context: Context) {
|
||||
class PipedApiUtil(context: Context) : IYoutubeExtractor {
|
||||
private var sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
private val countryCode = sharedPreferences.getString("locale", "")!!.ifEmpty { "US" }
|
||||
private val defaultPipedURL = "https://pipedapi.kavin.rocks/"
|
||||
|
|
@ -38,7 +38,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
return listOf()
|
||||
}
|
||||
|
||||
fun getVideoData(url : String) : Result<List<ResultItem>> {
|
||||
override fun getVideoData(url : String) : Result<List<ResultItem>> {
|
||||
val id = getIDFromYoutubeURL(url)
|
||||
val res = NetworkUtil.genericRequest("$pipedURL/streams/$id")
|
||||
if (res.length() == 0) {
|
||||
|
|
@ -49,7 +49,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
return Result.success(listOf(vid))
|
||||
}
|
||||
|
||||
fun getFormats(url: String) : Result<List<Format> > {
|
||||
override fun getFormats(url: String) : Result<List<Format> > {
|
||||
try {
|
||||
val id = getIDFromYoutubeURL(url)
|
||||
val res = NetworkUtil.genericRequest("$pipedURL/streams/$id")
|
||||
|
|
@ -67,7 +67,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>> {
|
||||
override 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 +88,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun search(query: String): Result<ArrayList<ResultItem>> {
|
||||
override fun search(query: String): Result<ArrayList<ResultItem>> {
|
||||
val items = arrayListOf<ResultItem>()
|
||||
val data = NetworkUtil.genericRequest("$pipedURL/search?q=$query&filter=videos®ion=${countryCode}")
|
||||
val dataArray = data.getJSONArray("items")
|
||||
|
|
@ -107,7 +107,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
|
||||
override fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
|
||||
val items = arrayListOf<ResultItem>()
|
||||
val data = NetworkUtil.genericRequest("$pipedURL/search?q=$query=&filter=music_songs®ion=${countryCode}")
|
||||
val dataArray = data.getJSONArray("items")
|
||||
|
|
@ -125,7 +125,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
return Result.success(items)
|
||||
}
|
||||
|
||||
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
|
||||
override 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 +140,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun getPlaylistData(id: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
|
||||
override suspend fun getPlaylistData(id: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
|
||||
val totalItems = mutableListOf<ResultItem>()
|
||||
val nextPageToken = ""
|
||||
var playlistName = ""
|
||||
|
|
@ -194,7 +194,7 @@ class PipedApiUtil(private val context: Context) {
|
|||
}
|
||||
|
||||
|
||||
fun getTrending(): ArrayList<ResultItem> {
|
||||
override fun getTrending(): ArrayList<ResultItem> {
|
||||
val items = arrayListOf<ResultItem>()
|
||||
val url = "$pipedURL/trending?region=${countryCode}"
|
||||
val res = NetworkUtil.genericArrayRequest(url)
|
||||
|
|
@ -209,6 +209,13 @@ class PipedApiUtil(private val context: Context) {
|
|||
return items
|
||||
}
|
||||
|
||||
override fun getChannelData(
|
||||
url: String,
|
||||
progress: (pagedResults: MutableList<ResultItem>) -> Unit
|
||||
): Result<List<ResultItem>> {
|
||||
return Result.failure(Throwable("Not yet implemented / supported?"))
|
||||
}
|
||||
|
||||
private fun createVideoFromPipedJSON(obj: JSONObject, url: String, ignoreFormatPreference : Boolean = false): ResultItem? {
|
||||
var video: ResultItem? = null
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ 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
|
||||
|
|
@ -38,7 +39,7 @@ import org.schabi.newpipe.extractor.utils.ExtractorHelper
|
|||
import java.util.Locale
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
class NewPipeUtil(context: Context) {
|
||||
class NewPipeUtil(context: Context) : IYoutubeExtractor {
|
||||
private var sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
private val countryCode = sharedPreferences.getString("locale", "")!!.ifEmpty { "US" }
|
||||
private val language = sharedPreferences.getString("app_language", "")!!.ifEmpty { "en" }
|
||||
|
|
@ -46,7 +47,7 @@ class NewPipeUtil(context: Context) {
|
|||
NewPipe.init(NewPipeDownloaderImpl(OkHttpClient.Builder()), Localization(language, countryCode))
|
||||
}
|
||||
|
||||
fun getVideoData(url : String) : Result<List<ResultItem>> {
|
||||
override 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())
|
||||
|
|
@ -56,7 +57,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getFormats(url: String) : Result<List<Format> > {
|
||||
override fun getFormats(url: String) : Result<List<Format> > {
|
||||
try {
|
||||
val streamInfo = StreamInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), url)
|
||||
val vid = createVideoFromStream(streamInfo, url)
|
||||
|
|
@ -68,7 +69,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getFormatsForAll(urls: List<String>, progress: (progress: ResultViewModel.MultipleFormatProgress) -> Unit) : Result<MutableList<MutableList<Format>>> {
|
||||
override 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 ->
|
||||
|
|
@ -85,7 +86,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun search(query: String): Result<ArrayList<ResultItem>> {
|
||||
override fun search(query: String): Result<ArrayList<ResultItem>> {
|
||||
try {
|
||||
val items = arrayListOf<ResultItem>()
|
||||
val res = SearchInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId),
|
||||
|
|
@ -111,7 +112,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
|
||||
@Throws(JSONException::class)
|
||||
fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
|
||||
override fun searchMusic(query: String): Result<ArrayList<ResultItem>> {
|
||||
try {
|
||||
val items = arrayListOf<ResultItem>()
|
||||
val res = SearchInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId),
|
||||
|
|
@ -135,7 +136,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getStreamingUrlAndChapters(url: String) : Result<Pair<List<String>, List<ChapterItem>?>> {
|
||||
override 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)
|
||||
|
|
@ -148,7 +149,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getChannelData(url: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
|
||||
override fun getChannelData(url: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
|
||||
try {
|
||||
val req = ChannelInfo.getInfo(ServiceList.YouTube, url)
|
||||
println(Gson().toJson(req))
|
||||
|
|
@ -214,7 +215,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getPlaylistData(playlistURL: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
|
||||
override suspend fun getPlaylistData(playlistURL: String, progress: (pagedResults: MutableList<ResultItem>) -> Unit) : Result<List<ResultItem>> {
|
||||
try {
|
||||
val totalItems = mutableListOf<ResultItem>()
|
||||
var nextPage : Page? = null
|
||||
|
|
@ -261,7 +262,7 @@ class NewPipeUtil(context: Context) {
|
|||
}
|
||||
|
||||
|
||||
fun getTrending(): ArrayList<ResultItem> {
|
||||
override fun getTrending(): ArrayList<ResultItem> {
|
||||
try {
|
||||
val items = arrayListOf<ResultItem>()
|
||||
val info = KioskInfo.getInfo(NewPipe.getService(ServiceList.YouTube.serviceId), "https://www.youtube.com/feed/trending")
|
||||
|
|
@ -434,7 +435,4 @@ class NewPipeUtil(context: Context) {
|
|||
query = el[0]
|
||||
return query!!
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -235,12 +235,14 @@
|
|||
</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>
|
||||
|
||||
|
|
@ -1494,4 +1496,10 @@
|
|||
<item>monthly</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="data_fetching_extractor_youtube">
|
||||
<item>YT_DLP</item>
|
||||
<item>NEWPIPE</item>
|
||||
<item>PIPED</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
|
@ -421,4 +421,5 @@
|
|||
<string name="continue_anyway">Continue Anyway</string>
|
||||
<string name="playlist_as_album">Use Playlist Name as Album Metadata</string>
|
||||
<string name="playlist_as_album_summary">If Album Metadata is not present, use playlist name instead</string>
|
||||
<string name="data_fetching_extractor_youtube">Data Fetching Extractor (YouTube)</string>
|
||||
</resources>
|
||||
|
|
@ -84,6 +84,15 @@
|
|||
android:summary="@string/api_key_summary"
|
||||
app:title="@string/api_key" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="NEWPIPE"
|
||||
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:useSimpleSummaryProvider="true"
|
||||
app:title="@string/data_fetching_extractor_youtube" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="yt-dlp"
|
||||
android:entries="@array/formats_source"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ Since Piped is currently broken and unusable, i implemented the NEWPIPE EXTRACTO
|
|||
- searching
|
||||
- youtube channel queries
|
||||
- formats
|
||||
The speed is as fast as piped and seems to be working. Will use that for the forseeable future, until further notice
|
||||
The speed is as fast as piped and seems to be working.
|
||||
Now you can select between piped, newpipe or strictly rely on yt-dlp
|
||||
|
||||
## Home screen filtering
|
||||
|
||||
|
|
@ -37,10 +38,16 @@ https://github.com/yt-dlp/yt-dlp/issues/10827
|
|||
- Prevented app selecting bad formats 233 and 234 when quick downloading
|
||||
- Fixed app not showing best quality and worst quality labels depending on the user language
|
||||
- Fixed app crashing when selecting formats of an instagram post with the same url
|
||||
- Added approx filesize in yt-dlp formats, somehow the app was not adding it lol
|
||||
- Added ability to remember text wrapping in download logs and terminal
|
||||
- if quick download enabled, added ability to show the download card while sharing the txt file on any download type
|
||||
- hide download size when enabling cutting because the size is unknown
|
||||
|
||||
## Note
|
||||
|
||||
Some people are asking for the ability to not use cache while downloading in usb storage. This is an android limitation. Even though you might have all files access, android still doesnt consider usb storage as main storage and cant directly write to it. So i have to use caching and then transfer the file.
|
||||
If anyone is knowledgeable to pull this off, dm me on telegram and we can make it happen. :)
|
||||
|
||||
Also for people cutting really long videos and its slow. Its a yt-dlp / ffmpeg issue of how they handle that, so it can't be helped. I guess its best to just download it fully and cut it somewhere else.
|
||||
|
||||
I could've released this sooner but i have been busy :/
|
||||
Loading…
Reference in a new issue