fixed korean
fixed please wait card not showing up
fixed audio format using mp4 containers
added portugese
added greek
fixed container not updating in multi select card
fixed queued swipe to delete bug
pull/199/head
deniscerri 3 years ago
parent f82d49c021
commit 3fe3de940b
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -10,7 +10,12 @@ def properties = new Properties()
def versionMajor = 1
def versionMinor = 6
def versionPatch = 3
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
def versionBuild = 1 // bump for dogfood builds, public betas, etc.
def versionExt = ""
if (versionBuild > 0){
versionExt = ".${versionBuild}-beta"
}
android {
namespace 'com.deniscerri.ytdlnis'
@ -37,7 +42,7 @@ android {
minSdk 23
targetSdk 33
versionCode versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
versionName "${versionMajor}.${versionMinor}.${versionPatch}${versionExt}"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
archivesBaseName = "YTDLnis-$versionName"
vectorDrawables {
@ -181,10 +186,8 @@ dependencies {
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVer"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVer"
implementation "com.squareup.retrofit2:retrofit:$retrofitVer"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVer"
implementation 'com.google.code.gson:gson:2.9.1'
implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.10"
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0'
implementation "com.google.android.exoplayer:exoplayer:2.18.5"

@ -24,7 +24,7 @@
-keep class com.google.gson.** { *; }
-keep class com.deniscerri.ytdlnis.database.models.AudioPreferences
-keep class com.deniscerri.ytdlnis.database.models.VideoPreferences
-keepclassmembers class * {
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keepclassmembers class <1> {
@ -67,6 +67,9 @@
-keepclassmembers class * extends androidx.work.Worker {
public <init>(android.content.Context,androidx.work.WorkerParameters);
}
-keep @androidx.room.Entity class *
-keep class * extends androidx.room.RoomDatabase
-dontwarn androidx.room.paging.**
-dontwarn com.google.android.exoplayer2.**
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.

@ -50,17 +50,18 @@ class ResultRepository(private val resultDao: ResultDao, private val commandTemp
suspend fun getOne(inputQuery: String, resetResults: Boolean) : ArrayList<ResultItem?>{
val infoUtil = InfoUtil(context)
val query = infoUtil.getIDFromYoutubeURL(inputQuery)
try {
val v = infoUtil.getVideo(query)
val v = infoUtil.getVideo(inputQuery)
if (resetResults) {
deleteAll()
itemCount.value = 1
itemCount.value = v.size
}else{
v!!.playlistTitle = "ytdlnis-Search"
v.forEach { it?.playlistTitle = "ytdlnis-Search" }
}
resultDao.insert(v!!)
return arrayListOf(v)
v.forEach {
resultDao.insert(it!!)
}
return ArrayList(v)
} catch (e: Exception) {
Log.e(tag, e.toString())
}
@ -82,10 +83,10 @@ class ResultRepository(private val resultDao: ResultDao, private val commandTemp
if (tmpToken == nextPageToken) break
nextPageToken = tmpToken
} while (true)
itemCount.value = items.size
items.forEach {
resultDao.insert(it!!)
}
itemCount.value = items.size
return items
}
@ -122,10 +123,6 @@ class ResultRepository(private val resultDao: ResultDao, private val commandTemp
resultDao.update(item)
}
fun getTemplates() : List<CommandTemplate> {
return commandTemplateDao.getAllTemplates()
}
fun getItemByURL(url: String): ResultItem {
return resultDao.getResultByURL(url)
}

@ -85,10 +85,10 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
"Search" -> {
res = repository.search(inputQuery, resetResults)
}
"Video" -> {
"YT_Video" -> {
res = repository.getOne(inputQuery, resetResults)
}
"Playlist" -> {
"YT_Playlist" -> {
res = repository.getPlaylist(inputQuery, resetResults)
}
"Default" -> {
@ -107,9 +107,9 @@ class ResultViewModel(application: Application) : AndroidViewModel(application)
val p = Pattern.compile("^(https?)://(www.)?(music.)?youtu(.be)?")
val m = p.matcher(inputQuery)
if (m.find()) {
type = "Video"
type = "YT_Video"
if (inputQuery.contains("playlist?list=")) {
type = "Playlist"
type = "YT_Playlist"
}
} else if (inputQuery.contains("http")) {
type = "Default"

@ -357,6 +357,7 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
when (direction) {
ItemTouchHelper.LEFT -> {
val deletedItem = items[position]
queuedDownloads.notifyItemChanged(position)
removeItem(deletedItem.id)
}

@ -12,13 +12,13 @@ import com.deniscerri.ytdlnis.database.models.ChapterItem
import com.deniscerri.ytdlnis.database.models.Format
import com.deniscerri.ytdlnis.database.models.ResultItem
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLRequest
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import retrofit2.Retrofit
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
@ -32,7 +32,6 @@ import java.util.regex.Pattern
class InfoUtil(private val context: Context) {
private var items: ArrayList<ResultItem?>
private lateinit var sharedPreferences: SharedPreferences
private lateinit var retrofit : Retrofit
private var key: String? = null
init {
@ -146,7 +145,9 @@ class InfoUtil(private val context: Context) {
var nextpage = res.getString("nextpage")
for (i in 0 until dataArray.length()){
val obj = dataArray.getJSONObject(i)
items.add(createVideoFromPipedJSON(obj, obj.getString("url").removePrefix("/watch?v=")))
val itm = createVideoFromPipedJSON(obj, obj.getString("url").removePrefix("/watch?v="))
itm?.playlistTitle = "YTDLnis"
items.add(itm)
}
if (nextpage == "null") nextpage = ""
return PlaylistTuple(nextpage, items)
@ -211,20 +212,20 @@ class InfoUtil(private val context: Context) {
}
@Throws(JSONException::class)
fun getVideo(id: String): ResultItem? {
fun getVideo(url: String): List<ResultItem?> {
try {
val id = getIDFromYoutubeURL(url)
if (key!!.isEmpty()) {
val res = genericRequest("$pipedURL/streams/$id")
return if (res.length() == 0) getFromYTDL("https://www.youtube.com/watch?v=$id")[0] else createVideoFromPipedJSON(
return if (res.length() == 0) getFromYTDL(url) else listOf(createVideoFromPipedJSON(
res, id
)
))
}
//short data
var res =
genericRequest("https://youtube.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=$id&key=$key")
if (!res.has("items")) return getFromYTDL("https://www.youtube.com/watch?v=$id")[0]
if (!res.has("items")) return getFromYTDL(url)
var duration = res.getJSONArray("items").getJSONObject(0).getJSONObject("contentDetails")
.getString("duration")
duration = formatDuration(duration)
@ -232,9 +233,9 @@ class InfoUtil(private val context: Context) {
res.put("videoID", id)
res.put("duration", duration)
fixThumbnail(res)
return createVideofromJSON(res)
return listOf(createVideofromJSON(res))
}catch (e: Exception){
return getFromYTDL("https://www.youtube.com/watch?v=$id")[0]
return getFromYTDL(url)
}
}
@ -697,9 +698,12 @@ class InfoUtil(private val context: Context) {
} else {
jsonObject.getString("webpage_url_basename")
}
var author: String? = ""
if (jsonObject.has("uploader")) {
author = jsonObject.getString("uploader")
var author: String = if (jsonObject.has("uploader")) jsonObject.getString("uploader") else ""
if (author.isEmpty() || author == "null"){
author = if (jsonObject.has("channel")) jsonObject.getString("channel") else ""
if (author.isEmpty() || author == "null"){
author = if (jsonObject.has("playlist_uploader")) jsonObject.getString("playlist_uploader") else ""
}
}
var duration = ""
runCatching {
@ -747,7 +751,7 @@ class InfoUtil(private val context: Context) {
}
}
val chaptersInJSON = if (jsonObject.has("formats") && jsonObject.get("formats") is JSONArray) jsonObject.getJSONArray("formats") else null
val chaptersInJSON = if (jsonObject.has("chapters") && jsonObject.get("chapters") is JSONArray) jsonObject.getJSONArray("chapters") else null
val listType: Type = object : TypeToken<List<ChapterItem>>() {}.type
var chapters : ArrayList<ChapterItem> = arrayListOf()
@ -803,9 +807,12 @@ class InfoUtil(private val context: Context) {
val youtubeDLResponse = YoutubeDL.getInstance().execute(request)
val jsonObject = JSONObject(youtubeDLResponse.out)
var author: String? = ""
if (jsonObject.has("uploader")) {
author = jsonObject.getString("uploader")
var author: String = if (jsonObject.has("uploader")) jsonObject.getString("uploader") else ""
if (author.isEmpty() || author == "null"){
author = if (jsonObject.has("channel")) jsonObject.getString("channel") else ""
if (author.isEmpty() || author == "null"){
author = if (jsonObject.has("playlist_uploader")) jsonObject.getString("playlist_uploader") else ""
}
}
var duration = ""

@ -49,7 +49,7 @@ class UpdateUtil(var context: Context) {
return
}
val versionNameInt = version.split("v")[1].replace(".","").toInt()
val currentVersionNameInt = BuildConfig.VERSION_NAME.replace(".","").toInt()
val currentVersionNameInt = BuildConfig.VERSION_CODE.toString().replace("0", "").substring(0, versionNameInt.toString().length).toInt()
if (currentVersionNameInt >= versionNameInt) {
result(context.getString(R.string.you_are_in_latest_version))
return

@ -132,7 +132,7 @@
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/container"
android:id="@+id/codec"
style="@style/Widget.Material3.FloatingActionButton.Large.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

@ -95,6 +95,7 @@
<item>bn</item>
<item>bs</item>
<item>de</item>
<item>el</item>
<item>es</item>
<item>fa</item>
<item>fr</item>

@ -6,6 +6,7 @@
<locale android:name="bn"/>
<locale android:name="bs"/>
<locale android:name="de"/>
<locale android:name="el"/>
<locale android:name="es"/>
<locale android:name="fa-IR"/>
<locale android:name="fr"/>

Loading…
Cancel
Save