mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-28 07:50:31 +05:30
download dialog
This commit is contained in:
parent
7159eb0472
commit
f8a0c949f9
@ -25,13 +25,13 @@
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "x86"
|
||||
"value": "armeabi-v7a"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 4,
|
||||
"versionName": "0.2.2",
|
||||
"outputFile": "app-x86-release.apk"
|
||||
"outputFile": "app-armeabi-v7a-release.apk"
|
||||
},
|
||||
{
|
||||
"type": "ONE_OF_MANY",
|
||||
@ -51,13 +51,13 @@
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "ABI",
|
||||
"value": "armeabi-v7a"
|
||||
"value": "x86"
|
||||
}
|
||||
],
|
||||
"attributes": [],
|
||||
"versionCode": 4,
|
||||
"versionName": "0.2.2",
|
||||
"outputFile": "app-armeabi-v7a-release.apk"
|
||||
"outputFile": "app-x86-release.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
|
96
app/src/main/java/com/github/libretube/DownloadDialog.kt
Normal file
96
app/src/main/java/com/github/libretube/DownloadDialog.kt
Normal file
@ -0,0 +1,96 @@
|
||||
package com.github.libretube
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
|
||||
|
||||
class DownloadDialog : DialogFragment() {
|
||||
private val TAG = "DownloadDialog"
|
||||
var vidName = arrayListOf<String>()
|
||||
var vidUrl = arrayListOf<String>()
|
||||
var audioName = arrayListOf<String>()
|
||||
var audioUrl = arrayListOf<String>()
|
||||
var selectedVideo = 0
|
||||
var selectedAudio = 0
|
||||
var extension = ".mkv"
|
||||
var duration = 0
|
||||
private lateinit var videoId: String
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return activity?.let {
|
||||
vidName = arguments?.getStringArrayList("videoName") as ArrayList<String>
|
||||
vidUrl = arguments?.getStringArrayList("videoUrl") as ArrayList<String>
|
||||
audioName = arguments?.getStringArrayList("audioName") as ArrayList<String>
|
||||
audioUrl = arguments?.getStringArrayList("audioUrl") as ArrayList<String>
|
||||
duration = arguments?.getInt("duration")!!
|
||||
videoId = arguments?.getString("videoId")!!
|
||||
val builder = AlertDialog.Builder(it)
|
||||
// Get the layout inflater
|
||||
val inflater = requireActivity().layoutInflater
|
||||
var view: View = inflater.inflate(R.layout.dialog_download, null)
|
||||
val videoSpinner = view.findViewById<Spinner>(R.id.video_spinner)
|
||||
val videoArrayAdapter =ArrayAdapter<String>(requireContext(),android.R.layout.simple_spinner_item,vidName)
|
||||
videoArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
videoSpinner.adapter=videoArrayAdapter
|
||||
videoSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>,
|
||||
view: View,
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
selectedVideo = position
|
||||
Log.d(TAG,selectedVideo.toString())
|
||||
}
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
val audioSpinner = view.findViewById<Spinner>(R.id.audio_spinner)
|
||||
val audioArrayAdapter = ArrayAdapter<String>(requireContext(),android.R.layout.simple_spinner_item,audioName)
|
||||
audioArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
audioSpinner.adapter = audioArrayAdapter
|
||||
audioSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>,
|
||||
view: View,
|
||||
position: Int,
|
||||
id: Long
|
||||
) {
|
||||
selectedAudio = position
|
||||
Log.d(TAG,selectedAudio.toString())
|
||||
}
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
val radioGroup = view.findViewById<RadioGroup>(R.id.radioGp)
|
||||
radioGroup.setOnCheckedChangeListener { group, checkedId ->
|
||||
val radio: RadioButton = view.findViewById(checkedId)
|
||||
extension = radio.text.toString()
|
||||
Log.d(TAG,extension)
|
||||
}
|
||||
view.findViewById<Button>(R.id.download).setOnClickListener {
|
||||
val intent = Intent(context,DownloadService::class.java)
|
||||
intent.putExtra("videoId",videoId)
|
||||
intent.putExtra("videoUrl",vidUrl[selectedVideo])
|
||||
intent.putExtra("audioUrl",audioUrl[selectedAudio])
|
||||
intent.putExtra("duration",duration)
|
||||
intent.putExtra("extension",extension)
|
||||
//intent.putExtra("command","-y -i ${response.videoStreams[which].url} -i ${response.audioStreams!![0].url} -c copy ${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/${videoId}.mkv")
|
||||
context?.startService(intent)
|
||||
dismiss()
|
||||
}
|
||||
builder.setView(view)
|
||||
builder.create()
|
||||
} ?: throw IllegalStateException("Activity cannot be null")
|
||||
}
|
||||
override fun onDestroy() {
|
||||
vidName.clear()
|
||||
vidUrl.clear()
|
||||
audioUrl.clear()
|
||||
audioName.clear()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
@ -12,25 +12,35 @@ import android.os.Environment
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.arthenica.ffmpegkit.FFmpegKit
|
||||
import java.io.File
|
||||
import java.lang.Exception
|
||||
|
||||
var IS_DOWNLOAD_RUNNING = false
|
||||
class DownloadService : Service(){
|
||||
val TAG = "DownloadService"
|
||||
private var downloadId: Long =0
|
||||
|
||||
private var downloadId: Long =-1
|
||||
private lateinit var videoId: String
|
||||
private lateinit var videoUrl: String
|
||||
private lateinit var audioUrl: String
|
||||
private lateinit var extension: String
|
||||
private var duration: Int = 0
|
||||
//private lateinit var command: String
|
||||
private lateinit var audioDir: File
|
||||
private lateinit var videoDir: File
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
IS_DOWNLOAD_RUNNING = true
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
videoId = intent?.getStringExtra("videoId")!!
|
||||
videoUrl = intent.getStringExtra("videoUrl")!!
|
||||
audioUrl = intent.getStringExtra("audioUrl")!!
|
||||
extension = intent.getStringExtra("extension")!!
|
||||
//command = intent.getStringExtra("command")!!
|
||||
duration = intent.getIntExtra("duration",1)
|
||||
downloadManager()
|
||||
@ -49,12 +59,15 @@ class DownloadService : Service(){
|
||||
f.mkdirs()
|
||||
Log.e(TAG, "Directory make")
|
||||
} else {
|
||||
f.deleteRecursively()
|
||||
f.mkdirs()
|
||||
Log.e(TAG, "Directory already have")
|
||||
}
|
||||
audioDir = File(f, "$videoId-audio")
|
||||
videoDir = File(f, "$videoId-video")
|
||||
try {
|
||||
Log.e(TAG, "Directory make")
|
||||
registerReceiver(onDownloadComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
|
||||
val request: DownloadManager.Request =
|
||||
DownloadManager.Request(Uri.parse(videoUrl))
|
||||
.setTitle("Video") // Title of the Download Notification
|
||||
@ -66,22 +79,11 @@ class DownloadService : Service(){
|
||||
val downloadManager: DownloadManager =
|
||||
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||
downloadId = downloadManager.enqueue(request)
|
||||
|
||||
registerReceiver(onDownloadComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
|
||||
if(audioUrl=="") downloadId = 0L
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Log.e(TAG, "download error $e")
|
||||
}
|
||||
}
|
||||
|
||||
private val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
//Fetching the download id received with the broadcast
|
||||
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
|
||||
//Checking if the received broadcast is for our enqueued download by matching download id
|
||||
if (downloadId == id) {
|
||||
Toast.makeText(this@DownloadService, "Download Completed", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
downloadId=0
|
||||
try{
|
||||
downloadId = 0L
|
||||
val request: DownloadManager.Request =
|
||||
DownloadManager.Request(Uri.parse(audioUrl))
|
||||
.setTitle("Audio") // Title of the Download Notification
|
||||
@ -94,8 +96,35 @@ class DownloadService : Service(){
|
||||
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||
downloadManager.enqueue(request)
|
||||
|
||||
}catch (e: Exception){
|
||||
Log.e(TAG, "audio download error $e")
|
||||
stopService(Intent(this,DownloadService::class.java))}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
//Fetching the download id received with the broadcast
|
||||
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
|
||||
//Checking if the received broadcast is for our enqueued download by matching download id
|
||||
if (downloadId == id) {
|
||||
downloadId=0L
|
||||
try{
|
||||
val request: DownloadManager.Request =
|
||||
DownloadManager.Request(Uri.parse(audioUrl))
|
||||
.setTitle("Audio") // Title of the Download Notification
|
||||
.setDescription("Downloading") // Description of the Download Notification
|
||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE) // Visibility of the download Notification
|
||||
.setDestinationUri(Uri.fromFile(audioDir))
|
||||
.setAllowedOverMetered(true) // Set if download is allowed on Mobile network
|
||||
.setAllowedOverRoaming(true) //
|
||||
val downloadManager: DownloadManager =
|
||||
applicationContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
|
||||
downloadManager.enqueue(request)
|
||||
}catch (e: Exception){}
|
||||
}else if (downloadId == 0L){
|
||||
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
/*val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val chan = NotificationChannel("service",
|
||||
@ -109,11 +138,10 @@ class DownloadService : Service(){
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
""
|
||||
}
|
||||
//Toast.makeText(this,command, Toast.LENGTH_SHORT).show()
|
||||
val pendingIntent: PendingIntent = PendingIntent.getActivity(
|
||||
this@DownloadService, 0, intent, 0)
|
||||
this@DownloadService, 0, intent, 0)*/
|
||||
//Sets the maximum progress as 100
|
||||
val progressMax = 100
|
||||
/*val progressMax = 100
|
||||
//Creating a notification and setting its various attributes
|
||||
val notification =
|
||||
NotificationCompat.Builder(this@DownloadService, channelId)
|
||||
@ -125,9 +153,26 @@ class DownloadService : Service(){
|
||||
.setOnlyAlertOnce(true)
|
||||
.setProgress(progressMax, 0, true)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true)
|
||||
|
||||
FFmpegKit.executeAsync("-y -i $videoDir -i $audioDir -c copy ${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/${videoId}.mkv",
|
||||
.setAutoCancel(true)*/
|
||||
val libreTube = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"LibreTube")
|
||||
if (!libreTube.exists()) {
|
||||
libreTube.mkdirs()
|
||||
Log.e(TAG, "libreTube Directory make")
|
||||
} else {
|
||||
Log.e(TAG, "libreTube Directory already have")
|
||||
}
|
||||
var command: String = when {
|
||||
videoUrl=="" -> {
|
||||
"-y -i $audioDir -c copy ${libreTube}/${videoId}-audio$extension"
|
||||
}
|
||||
audioUrl=="" -> {
|
||||
"-y -i $videoDir -c copy ${libreTube}/${videoId}-video$extension"
|
||||
}
|
||||
else -> {
|
||||
"-y -i $videoDir -i $audioDir -c copy ${libreTube}/${videoId}$extension"
|
||||
}
|
||||
}
|
||||
FFmpegKit.executeAsync(command,
|
||||
{ session ->
|
||||
val state = session.state
|
||||
val returnCode = session.returnCode
|
||||
@ -146,27 +191,33 @@ class DownloadService : Service(){
|
||||
val f = File(path, folder_main)
|
||||
f.deleteRecursively()
|
||||
stopForeground(true)
|
||||
//Toast.makeText(this@DownloadService, R.string.dlcomplete, Toast.LENGTH_LONG).show()
|
||||
stopService(Intent(this@DownloadService,DownloadService::class.java))
|
||||
}, {
|
||||
// CALLED WHEN SESSION PRINTS LOGS
|
||||
Log.e(TAG,it.message.toString())
|
||||
}) {
|
||||
// CALLED WHEN SESSION GENERATES STATISTICS
|
||||
Log.e(TAG+"stat",it.time.toString())
|
||||
val progress = it.time/(10*duration!!)
|
||||
/*val progress = it.time/(10*duration!!)
|
||||
if (progress<1){
|
||||
notification
|
||||
.setProgress(progressMax, progress.toInt(), false)
|
||||
service.notify(1,notification.build())
|
||||
}*/
|
||||
}
|
||||
}
|
||||
startForeground(1,notification.build())
|
||||
//startForeground(1,notification.build())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
try {
|
||||
unregisterReceiver(onDownloadComplete)
|
||||
}catch (e: Exception){}
|
||||
IS_DOWNLOAD_RUNNING = false
|
||||
Log.d(TAG,"dl finished!")
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import android.app.Activity
|
||||
import android.app.ActivityManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
@ -366,8 +365,10 @@ class PlayerFragment : Fragment() {
|
||||
}
|
||||
//check if livestream
|
||||
if (response.duration!!>0){
|
||||
|
||||
//download clicked
|
||||
relDownloadVideo.setOnClickListener {
|
||||
if(!IS_DOWNLOAD_RUNNING){
|
||||
val mainActivity = activity as MainActivity
|
||||
Log.e(TAG,"download button clicked!")
|
||||
if (SDK_INT >= Build.VERSION_CODES.R) {
|
||||
@ -399,44 +400,38 @@ class PlayerFragment : Fragment() {
|
||||
)
|
||||
}
|
||||
}
|
||||
val builderr: AlertDialog.Builder? = activity?.let {
|
||||
AlertDialog.Builder(it)
|
||||
var vidName = arrayListOf<String>()
|
||||
vidName.add("No video")
|
||||
var vidUrl = arrayListOf<String>()
|
||||
vidUrl.add("")
|
||||
for (vid in response.videoStreams!!){
|
||||
val name = vid.quality +" "+ vid.format
|
||||
vidName.add(name)
|
||||
vidUrl.add(vid.url!!)
|
||||
}
|
||||
var audioName = arrayListOf<String>()
|
||||
audioName.add("No audio")
|
||||
var audioUrl = arrayListOf<String>()
|
||||
audioUrl.add("")
|
||||
for (audio in response.audioStreams!!){
|
||||
val name = audio.quality +" "+ audio.format
|
||||
audioName.add(name)
|
||||
audioUrl.add(audio.url!!)
|
||||
}
|
||||
val newFragment = DownloadDialog()
|
||||
var bundle = Bundle()
|
||||
bundle.putStringArrayList("videoName",vidName)
|
||||
bundle.putStringArrayList("videoUrl",vidUrl)
|
||||
bundle.putStringArrayList("audioName",audioName)
|
||||
bundle.putStringArrayList("audioUrl",audioUrl)
|
||||
bundle.putString("videoId",videoId)
|
||||
bundle.putInt("duration",response.duration)
|
||||
newFragment.arguments = bundle
|
||||
newFragment.show(childFragmentManager, "Download")
|
||||
}else{
|
||||
Toast.makeText(context, R.string.dlisinprogress, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
var videos = videosNameArray.drop(1).toTypedArray()
|
||||
builderr!!.setTitle(R.string.choose_quality_dialog)
|
||||
.setItems(videos,
|
||||
DialogInterface.OnClickListener { _, which ->
|
||||
val intent = Intent(context,DownloadService::class.java)
|
||||
intent.putExtra("videoId",videoId)
|
||||
intent.putExtra("videoUrl",response.videoStreams[which].url)
|
||||
intent.putExtra("audioUrl",response.audioStreams!![0].url)
|
||||
intent.putExtra("duration",response.duration)
|
||||
//intent.putExtra("command","-y -i ${response.videoStreams[which].url} -i ${response.audioStreams!![0].url} -c copy ${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/${videoId}.mkv")
|
||||
context?.startService(intent)
|
||||
/*FFmpegKit.executeAsync("-y -i ${response.videoStreams[which].url} -i ${response.audioStreams!![0].url} -c copy ${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/${videoId}.mkv",
|
||||
{ session ->
|
||||
val state = session.state
|
||||
val returnCode = session.returnCode
|
||||
// CALLED WHEN SESSION IS EXECUTED
|
||||
Log.d(
|
||||
TAG,
|
||||
String.format(
|
||||
"FFmpeg process exited with state %s and rc %s.%s",
|
||||
state,
|
||||
returnCode,
|
||||
session.failStackTrace
|
||||
)
|
||||
)
|
||||
}, {
|
||||
// CALLED WHEN SESSION PRINTS LOGS
|
||||
Log.e(TAG,it.message.toString())
|
||||
}) {
|
||||
// CALLED WHEN SESSION GENERATES STATISTICS
|
||||
Log.e(TAG,it.time.toString())
|
||||
}*/
|
||||
})
|
||||
val dialog: AlertDialog? = builderr?.create()
|
||||
dialog?.show()
|
||||
}
|
||||
}else{
|
||||
Toast.makeText(context,R.string.cannotDownload, Toast.LENGTH_SHORT).show()
|
||||
@ -449,15 +444,6 @@ class PlayerFragment : Fragment() {
|
||||
|
||||
}
|
||||
|
||||
/* private fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
|
||||
val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
|
||||
for (service in manager!!.getRunningServices(Int.MAX_VALUE)) {
|
||||
if (serviceClass.name == service.service.className) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}*/
|
||||
private fun isSubscribed(button: MaterialButton, channel_id: String){
|
||||
@SuppressLint("ResourceAsColor")
|
||||
fun run() {
|
||||
|
53
app/src/main/res/layout/dialog_download.xml
Normal file
53
app/src/main/res/layout/dialog_download.xml
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
|
||||
|
||||
<ImageView
|
||||
android:src="@drawable/ic_libretube_foreground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:scaleType="center"
|
||||
android:background="#CD5757"
|
||||
android:contentDescription="@string/app_name" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/video_spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
/>
|
||||
<Spinner
|
||||
android:id="@+id/audio_spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"/>
|
||||
<RadioGroup
|
||||
android:id="@+id/radioGp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp">
|
||||
<RadioButton
|
||||
android:id="@+id/mkv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=".mkv"
|
||||
android:checked="true"/>
|
||||
<RadioButton
|
||||
android:id="@+id/mp4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=".mp4"/>
|
||||
</RadioGroup>
|
||||
<Button
|
||||
android:id="@+id/download"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/download"
|
||||
android:padding="8dp"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_gravity="center"/>
|
||||
</LinearLayout>
|
@ -104,7 +104,8 @@
|
||||
android:id="@+id/relPlayer_download"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/player_download"
|
||||
|
@ -24,4 +24,6 @@
|
||||
<string name="please_login">Please Login or Register from the settings to show your Subscriptions!</string>
|
||||
<string name="subscribeIsEmpty">Subscribe to some channels first!</string>
|
||||
<string name="cannotDownload">Can\'t Download this stream!</string>
|
||||
<string name="dlcomplete">Download is completed!</string>
|
||||
<string name="dlisinprogress">Another Download is already in progress please wait till it\'s finished!</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user