mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 08:30:44 +00:00
Merge branch 'backgroundPlayback'
This commit is contained in:
commit
72289ced39
@ -2,8 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="org.schabi.newpipe" >
|
package="org.schabi.newpipe" >
|
||||||
|
|
||||||
<uses-permission android:name= "android.permission.INTERNET" />
|
<uses-permission android:name= "android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name= "android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<application
|
<application
|
||||||
@ -74,6 +74,12 @@
|
|||||||
android:parentActivityName=".VideoItemDetailActivity"
|
android:parentActivityName=".VideoItemDetailActivity"
|
||||||
tools:ignore="UnusedAttribute">
|
tools:ignore="UnusedAttribute">
|
||||||
</activity>
|
</activity>
|
||||||
|
<!--TODO: make label a translatable string -->
|
||||||
|
<service
|
||||||
|
android:name=".BackgroundPlayer"
|
||||||
|
android:label="NewPipe Background Player"
|
||||||
|
android:exported="false" >
|
||||||
|
</service>
|
||||||
<activity
|
<activity
|
||||||
android:name=".SettingsActivity"
|
android:name=".SettingsActivity"
|
||||||
android:label="@string/title_activity_settings" >
|
android:label="@string/title_activity_settings" >
|
||||||
|
@ -120,6 +120,9 @@ class ActionBarHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Log.e(TAG, "FAILED to set audioStream value!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectFormatItem(int i) {
|
private void selectFormatItem(int i) {
|
||||||
@ -136,7 +139,7 @@ class ActionBarHandler {
|
|||||||
MenuItem castItem = menu.findItem(R.id.action_play_with_kodi);
|
MenuItem castItem = menu.findItem(R.id.action_play_with_kodi);
|
||||||
|
|
||||||
castItem.setVisible(defaultPreferences
|
castItem.setVisible(defaultPreferences
|
||||||
.getBoolean(activity.getString(R.string.showPlayWidthKodiPreference), false));
|
.getBoolean(activity.getString(R.string.showPlayWithKodiPreference), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onItemSelected(MenuItem item) {
|
public boolean onItemSelected(MenuItem item) {
|
||||||
@ -184,7 +187,7 @@ class ActionBarHandler {
|
|||||||
// ----------- THE MAGIC MOMENT ---------------
|
// ----------- THE MAGIC MOMENT ---------------
|
||||||
if(!videoTitle.isEmpty()) {
|
if(!videoTitle.isEmpty()) {
|
||||||
if (PreferenceManager.getDefaultSharedPreferences(activity)
|
if (PreferenceManager.getDefaultSharedPreferences(activity)
|
||||||
.getBoolean(activity.getString(R.string.useExternalPlayer), false)) {
|
.getBoolean(activity.getString(R.string.useExternalVideoPlayer), false)) {
|
||||||
|
|
||||||
// External Player
|
// External Player
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
@ -293,14 +296,32 @@ class ActionBarHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playAudio() {
|
public void playAudio() {
|
||||||
Intent intent = new Intent();
|
|
||||||
|
boolean externalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||||
|
.getBoolean(activity.getString(R.string.useExternalAudioPlayer), false);
|
||||||
|
Intent intent;
|
||||||
|
if (!externalAudioPlayer)//internal (background) music player: explicit intent
|
||||||
|
{
|
||||||
|
intent = new Intent(activity, BackgroundPlayer.class);
|
||||||
|
|
||||||
|
intent.setAction(Intent.ACTION_VIEW);
|
||||||
|
Log.i(TAG, "audioStream is null:" + (audioStream == null));
|
||||||
|
Log.i(TAG, "audioStream.url is null:"+(audioStream.url==null));
|
||||||
|
intent.setDataAndType(Uri.parse(audioStream.url),
|
||||||
|
MediaFormat.getMimeById(audioStream.format));
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
|
||||||
|
intent.putExtra("title", videoTitle);
|
||||||
|
activity.startService(intent);
|
||||||
|
} else {
|
||||||
|
intent = new Intent();
|
||||||
try {
|
try {
|
||||||
intent.setAction(Intent.ACTION_VIEW);
|
intent.setAction(Intent.ACTION_VIEW);
|
||||||
intent.setDataAndType(Uri.parse(audioStream.url),
|
intent.setDataAndType(Uri.parse(audioStream.url),
|
||||||
MediaFormat.getMimeById(audioStream.format));
|
MediaFormat.getMimeById(audioStream.format));
|
||||||
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
|
intent.putExtra(Intent.EXTRA_TITLE, videoTitle);
|
||||||
intent.putExtra("title", videoTitle);
|
intent.putExtra("title", videoTitle);
|
||||||
|
|
||||||
activity.startActivity(intent); // HERE !!!
|
activity.startActivity(intent); // HERE !!!
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -327,3 +348,4 @@ class ActionBarHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
255
app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
Normal file
255
app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.support.v7.app.NotificationCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Adam Howard on 08/11/15.
|
||||||
|
* Copyright (c) Adam Howard <achdisposable1@gmail.com> 2015
|
||||||
|
*
|
||||||
|
* BackgroundPlayer.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**Plays the audio stream of videos in the background.*/
|
||||||
|
public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPreparedListener*/ {
|
||||||
|
|
||||||
|
private static final String TAG = BackgroundPlayer.class.toString();
|
||||||
|
private static final String ACTION_STOP = TAG+".STOP";
|
||||||
|
private static final String ACTION_PLAYPAUSE = TAG+".PLAYPAUSE";
|
||||||
|
|
||||||
|
public BackgroundPlayer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
/*PendingIntent pi = PendingIntent.getActivity(this, 0,
|
||||||
|
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);*/
|
||||||
|
super.onCreate();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
Toast.makeText(this, "Playing in background", Toast.LENGTH_SHORT).show();//todo:translation string
|
||||||
|
|
||||||
|
String source = intent.getDataString();
|
||||||
|
//Log.i(TAG, "backgroundPLayer source:"+source);
|
||||||
|
String videoTitle = intent.getStringExtra("title");
|
||||||
|
|
||||||
|
//do nearly everything in a separate thread
|
||||||
|
PlayerThread player = new PlayerThread(source, videoTitle, this);
|
||||||
|
player.start();
|
||||||
|
|
||||||
|
// If we get killed after returning here, don't restart
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
// We don't provide binding (yet?), so return null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
//Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PlayerThread extends Thread {
|
||||||
|
MediaPlayer mediaPlayer;
|
||||||
|
private String source;
|
||||||
|
private String title;
|
||||||
|
private int noteID = TAG.hashCode();
|
||||||
|
private BackgroundPlayer owner;
|
||||||
|
private NotificationManager noteMgr;
|
||||||
|
private NotificationCompat.Builder noteBuilder;
|
||||||
|
private WifiManager.WifiLock wifiLock;
|
||||||
|
|
||||||
|
public PlayerThread(String src, String title, BackgroundPlayer owner) {
|
||||||
|
this.source = src;
|
||||||
|
this.title = title;
|
||||||
|
this.owner = owner;
|
||||||
|
mediaPlayer = new MediaPlayer();
|
||||||
|
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);//cpu lock
|
||||||
|
try {
|
||||||
|
mediaPlayer.setDataSource(source);
|
||||||
|
mediaPlayer.prepare(); //We are already in a separate worker thread,
|
||||||
|
//so calling the blocking prepare() method should be ok
|
||||||
|
|
||||||
|
//alternatively:
|
||||||
|
//mediaPlayer.setOnPreparedListener(this);
|
||||||
|
//mediaPlayer.prepareAsync(); //prepare async to not block main thread
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
ioe.printStackTrace();
|
||||||
|
Log.e(TAG, "video source:" + source);
|
||||||
|
Log.e(TAG, "video title:" + title);
|
||||||
|
//can't do anything useful without a file to play; exit early
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiManager wifiMgr = ((WifiManager)getSystemService(Context.WIFI_SERVICE));
|
||||||
|
wifiLock = wifiMgr.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG);
|
||||||
|
|
||||||
|
mediaPlayer.setOnCompletionListener(new EndListener(wifiLock));//listen for end of video
|
||||||
|
|
||||||
|
//get audio focus
|
||||||
|
/*
|
||||||
|
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
|
||||||
|
AudioManager.AUDIOFOCUS_GAIN);
|
||||||
|
|
||||||
|
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||||
|
// could not get audio focus.
|
||||||
|
}*/
|
||||||
|
wifiLock.acquire();
|
||||||
|
mediaPlayer.start();
|
||||||
|
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.setPriority(Integer.MAX_VALUE);
|
||||||
|
filter.addAction(ACTION_PLAYPAUSE);
|
||||||
|
filter.addAction(ACTION_STOP);
|
||||||
|
registerReceiver(broadcastReceiver, filter);
|
||||||
|
|
||||||
|
PendingIntent playPI = PendingIntent.getBroadcast(owner, noteID, new Intent(ACTION_PLAYPAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
NotificationCompat.Action playButton = new NotificationCompat.Action.Builder
|
||||||
|
(R.drawable.ic_play_arrow_white_48dp, "Play", playPI).build();
|
||||||
|
|
||||||
|
NotificationCompat.Action pauseButton = new NotificationCompat.Action.Builder
|
||||||
|
(R.drawable.ic_play_arrow_white_48dp, "Pause", playPI).build();
|
||||||
|
|
||||||
|
PendingIntent stopPI = PendingIntent.getBroadcast(owner, noteID,
|
||||||
|
new Intent(ACTION_STOP), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
//todo: make it so that tapping the notification brings you back to the Video's DetailActivity
|
||||||
|
//using setContentIntent
|
||||||
|
noteBuilder = new NotificationCompat.Builder(owner);
|
||||||
|
noteBuilder
|
||||||
|
.setPriority(Notification.PRIORITY_LOW)
|
||||||
|
.setCategory(Notification.CATEGORY_TRANSPORT)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText("NewPipe is playing in the background")//todo: translation string
|
||||||
|
//.setAutoCancel(!mediaPlayer.isPlaying())
|
||||||
|
.setOngoing(true)
|
||||||
|
.setDeleteIntent(stopPI)
|
||||||
|
//.setProgress(vidLength, 0, false) //doesn't fit with Notification.MediaStyle
|
||||||
|
.setSmallIcon(R.mipmap.ic_launcher)
|
||||||
|
.setTicker(title + " - NewPipe")
|
||||||
|
.addAction(playButton);
|
||||||
|
/* .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
|
.setLargeIcon(cover)*/
|
||||||
|
|
||||||
|
noteBuilder.setStyle(new NotificationCompat.MediaStyle()
|
||||||
|
//.setMediaSession(mMediaSession.getSessionToken())
|
||||||
|
.setShowActionsInCompactView(new int[] {0})
|
||||||
|
.setShowCancelButton(true)
|
||||||
|
.setCancelButtonIntent(stopPI)
|
||||||
|
);
|
||||||
|
|
||||||
|
startForeground(noteID, noteBuilder.build());
|
||||||
|
|
||||||
|
//currently decommissioned progressbar looping update code - works, but doesn't fit inside
|
||||||
|
//Notification.MediaStyle Notification layout.
|
||||||
|
noteMgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
/*
|
||||||
|
//update every 2s or 4 times in the video, whichever is shorter
|
||||||
|
int sleepTime = Math.min(2000, (int)((double)vidLength/4));
|
||||||
|
while(mediaPlayer.isPlaying()) {
|
||||||
|
noteBuilder.setProgress(vidLength, mediaPlayer.getCurrentPosition(), false);
|
||||||
|
noteMgr.notify(noteID, noteBuilder.build());
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepTime);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(TAG, "sleep failure");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
Log.i(TAG, "received broadcast action:"+action);
|
||||||
|
if(action.equals(ACTION_PLAYPAUSE)) {
|
||||||
|
if(mediaPlayer.isPlaying()) {
|
||||||
|
mediaPlayer.pause();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//reacquire CPU lock after releasing it on pause
|
||||||
|
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
|
||||||
|
mediaPlayer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(action.equals(ACTION_STOP)) {
|
||||||
|
mediaPlayer.stop();//this auto-releases CPU lock
|
||||||
|
afterPlayCleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void afterPlayCleanup() {
|
||||||
|
//noteBuilder.setProgress(0, 0, false);//remove progress bar
|
||||||
|
noteMgr.cancel(noteID);//remove notification
|
||||||
|
unregisterReceiver(broadcastReceiver);
|
||||||
|
mediaPlayer.release();//release mediaPlayer's system resources
|
||||||
|
|
||||||
|
|
||||||
|
wifiLock.release();//release wifilock
|
||||||
|
stopForeground(true);//remove foreground status of service; make us killable
|
||||||
|
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EndListener implements MediaPlayer.OnCompletionListener {
|
||||||
|
private WifiManager.WifiLock wl;
|
||||||
|
public EndListener(WifiManager.WifiLock wifiLock) {
|
||||||
|
this.wl = wifiLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompletion(MediaPlayer mp) {
|
||||||
|
afterPlayCleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
private class ListenerThread extends Thread implements AudioManager.OnAudioFocusChangeListener {
|
||||||
|
@Override
|
||||||
|
public void onAudioFocusChange(int focusChange) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
@ -30,6 +30,6 @@ public interface StreamingService {
|
|||||||
|
|
||||||
/**When a VIEW_ACTION is caught this function will test if the url delivered within the calling
|
/**When a VIEW_ACTION is caught this function will test if the url delivered within the calling
|
||||||
Intent was meant to be watched with this Service.
|
Intent was meant to be watched with this Service.
|
||||||
Return false if this service shall not allow to be callean through ACTIONs.*/
|
Return false if this service shall not allow to be called through ACTIONs.*/
|
||||||
boolean acceptUrl(String videoUrl);
|
boolean acceptUrl(String videoUrl);
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,16 @@ public class YoutubeVideoExtractor extends VideoExtractor {
|
|||||||
//todo: replace this with a call to getVideoId, if possible
|
//todo: replace this with a call to getVideoId, if possible
|
||||||
videoInfo.id = matchGroup1("v=([0-9a-zA-Z_-]{11})", pageUrl);
|
videoInfo.id = matchGroup1("v=([0-9a-zA-Z_-]{11})", pageUrl);
|
||||||
|
|
||||||
|
if(videoInfo.audioStreams == null
|
||||||
|
|| videoInfo.audioStreams.length == 0) {
|
||||||
|
Log.e(TAG, "uninitialised audio streams!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(videoInfo.videoStreams == null
|
||||||
|
|| videoInfo.videoStreams.length == 0) {
|
||||||
|
Log.e(TAG, "uninitialised video streams!");
|
||||||
|
}
|
||||||
|
|
||||||
videoInfo.age_limit = 0;
|
videoInfo.age_limit = 0;
|
||||||
|
|
||||||
//average rating
|
//average rating
|
||||||
@ -445,13 +455,14 @@ public class YoutubeVideoExtractor extends VideoExtractor {
|
|||||||
try {
|
try {
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
parser.setInput(new StringReader(dashDoc));
|
parser.setInput(new StringReader(dashDoc));
|
||||||
int eventType = parser.getEventType();
|
|
||||||
String tagName = "";
|
String tagName = "";
|
||||||
String currentMimeType = "";
|
String currentMimeType = "";
|
||||||
int currentBandwidth = -1;
|
int currentBandwidth = -1;
|
||||||
int currentSamplingRate = -1;
|
int currentSamplingRate = -1;
|
||||||
boolean currentTagIsBaseUrl = false;
|
boolean currentTagIsBaseUrl = false;
|
||||||
while(eventType != XmlPullParser.END_DOCUMENT) {
|
for(int eventType = parser.getEventType();
|
||||||
|
eventType != XmlPullParser.END_DOCUMENT;
|
||||||
|
eventType = parser.next() ) {
|
||||||
switch(eventType) {
|
switch(eventType) {
|
||||||
case XmlPullParser.START_TAG:
|
case XmlPullParser.START_TAG:
|
||||||
tagName = parser.getName();
|
tagName = parser.getName();
|
||||||
@ -465,8 +476,8 @@ public class YoutubeVideoExtractor extends VideoExtractor {
|
|||||||
} else if(tagName.equals("BaseURL")) {
|
} else if(tagName.equals("BaseURL")) {
|
||||||
currentTagIsBaseUrl = true;
|
currentTagIsBaseUrl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XmlPullParser.TEXT:
|
case XmlPullParser.TEXT:
|
||||||
if(currentTagIsBaseUrl &&
|
if(currentTagIsBaseUrl &&
|
||||||
(currentMimeType.contains("audio"))) {
|
(currentMimeType.contains("audio"))) {
|
||||||
@ -479,16 +490,14 @@ public class YoutubeVideoExtractor extends VideoExtractor {
|
|||||||
audioStreams.add(new VideoInfo.AudioStream(parser.getText(),
|
audioStreams.add(new VideoInfo.AudioStream(parser.getText(),
|
||||||
format, currentBandwidth, currentSamplingRate));
|
format, currentBandwidth, currentSamplingRate));
|
||||||
}
|
}
|
||||||
|
//missing break here?
|
||||||
case XmlPullParser.END_TAG:
|
case XmlPullParser.END_TAG:
|
||||||
if(tagName.equals("AdaptationSet")) {
|
if(tagName.equals("AdaptationSet")) {
|
||||||
currentMimeType = "";
|
currentMimeType = "";
|
||||||
} else if(tagName.equals("BaseURL")) {
|
} else if(tagName.equals("BaseURL")) {
|
||||||
currentTagIsBaseUrl = false;
|
currentTagIsBaseUrl = false;
|
||||||
|
}//no break needed here
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
eventType = parser.next();
|
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -582,10 +591,7 @@ public class YoutubeVideoExtractor extends VideoExtractor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
Context.exit();
|
Context.exit();
|
||||||
if(result != null)
|
return (result == null ? "" : result.toString());
|
||||||
return result.toString();
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String cleanUrl(String complexUrl) {
|
private String cleanUrl(String complexUrl) {
|
||||||
|
BIN
app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 283 B |
BIN
app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 220 B |
BIN
app/src/main/res/drawable-xhdpi/ic_play_arrow_white_48dp.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_play_arrow_white_48dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 343 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 461 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 605 B |
@ -6,9 +6,10 @@
|
|||||||
<string name="settingsCategoryEtc">settings_category_etc</string>
|
<string name="settingsCategoryEtc">settings_category_etc</string>
|
||||||
<!-- Key values -->
|
<!-- Key values -->
|
||||||
<string name="downloadPathPreference">download_path_preference</string>
|
<string name="downloadPathPreference">download_path_preference</string>
|
||||||
<string name="useExternalPlayer">use_external_player</string>
|
<string name="useExternalVideoPlayer">use_external_video_player</string>
|
||||||
|
<string name="useExternalAudioPlayer">use_external_audio_player</string>
|
||||||
<string name="autoPlayThroughIntent">autoplay_through_intent</string>
|
<string name="autoPlayThroughIntent">autoplay_through_intent</string>
|
||||||
<string name="defaultResolutionPreference">default_resulution_preference</string>
|
<string name="defaultResolutionPreference">default_resolution_preference</string>
|
||||||
<string-array name="resolutionList">
|
<string-array name="resolutionList">
|
||||||
<item>720p</item>
|
<item>720p</item>
|
||||||
<item>360p</item>
|
<item>360p</item>
|
||||||
@ -16,7 +17,7 @@
|
|||||||
<item>144p</item>
|
<item>144p</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="defaultResolutionListItem">360p</string>
|
<string name="defaultResolutionListItem">360p</string>
|
||||||
<string name="showPlayWidthKodiPreference">show_play_with_kodi_preference</string>
|
<string name="showPlayWithKodiPreference">show_play_with_kodi_preference</string>
|
||||||
<string name="defaultAudioFormatPreference">default_audio_format</string>
|
<string name="defaultAudioFormatPreference">default_audio_format</string>
|
||||||
<string-array name="audioFormatDescriptionList">
|
<string-array name="audioFormatDescriptionList">
|
||||||
<item>@string/webMAudioDescription</item>
|
<item>@string/webMAudioDescription</item>
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
<string name="chooseBrowser">Choose browser:</string>
|
<string name="chooseBrowser">Choose browser:</string>
|
||||||
<string name="screenRotation">rotation</string>
|
<string name="screenRotation">rotation</string>
|
||||||
<string name="title_activity_settings">Settings</string>
|
<string name="title_activity_settings">Settings</string>
|
||||||
<string name="useExternalPlayerTitle">Use external player</string>
|
<string name="useExternalVideoPlayerTitle">Use external video player</string>
|
||||||
|
<string name="useExternalAudioPlayerTitle">Use external audio player</string>
|
||||||
<string name="downloadLocation">Download location</string>
|
<string name="downloadLocation">Download location</string>
|
||||||
<string name="downloadLocationSummary">Path to store downloaded videos in.</string>
|
<string name="downloadLocationSummary">Path to store downloaded videos in.</string>
|
||||||
<string name="downloadLocationDialogTitle">Enter download path</string>
|
<string name="downloadLocationDialogTitle">Enter download path</string>
|
||||||
|
@ -8,8 +8,13 @@
|
|||||||
android:title="@string/settingsCategoryVideoAudioTitle">
|
android:title="@string/settingsCategoryVideoAudioTitle">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="@string/useExternalPlayer"
|
android:key="@string/useExternalVideoPlayer"
|
||||||
android:title="@string/useExternalPlayerTitle"
|
android:title="@string/useExternalVideoPlayerTitle"
|
||||||
|
android:defaultValue="false"/>
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="@string/useExternalAudioPlayer"
|
||||||
|
android:title="@string/useExternalAudioPlayerTitle"
|
||||||
android:defaultValue="false"/>
|
android:defaultValue="false"/>
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
@ -32,7 +37,7 @@
|
|||||||
android:title="@string/settingsCategoryVideoInfoTittle">
|
android:title="@string/settingsCategoryVideoInfoTittle">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="@string/showPlayWidthKodiPreference"
|
android:key="@string/showPlayWithKodiPreference"
|
||||||
android:title="@string/showPlayWithKodiTitle"
|
android:title="@string/showPlayWithKodiTitle"
|
||||||
android:summary="@string/showPlayWithKodiSummary"
|
android:summary="@string/showPlayWithKodiSummary"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
Loading…
Reference in New Issue
Block a user