mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-11 09:40:26 +00:00
Added precaching of next track when playing track is almost finished.
This commit is contained in:
parent
a0c37bca1f
commit
32baa51f0d
@ -13,6 +13,7 @@
|
||||
<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:text="Browse by:" android:layout_width="fill_parent" android:background="@color/headlineColor" android:textSize="16sp" android:padding="4sp"></TextView>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:text="Genre" android:id="@+id/GenresButton"></Button>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:id="@+id/ArtistsButton" android:text="Artist"></Button>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView android:id="@+id/StatusView" android:text="Status: -" android:layout_width="fill_parent" android:background="@color/headlineColor" android:textSize="16sp" android:padding="4sp" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_weight="0.1"></TextView>
|
||||
|
@ -1,2 +1,5 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"><item android:title="@string/menu_settings" android:id="@+id/context_settings" android:enabled="true" android:visible="true"></item>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:title="@string/menu_browse" android:id="@+id/context_browse" android:enabled="true" android:visible="true"></item>
|
||||
<item android:title="@string/menu_controls" android:id="@+id/context_controls" android:enabled="true" android:visible="true"></item>
|
||||
<item android:title="@string/menu_settings" android:id="@+id/context_settings" android:enabled="true" android:visible="true"></item>
|
||||
</menu>
|
||||
|
@ -16,4 +16,6 @@
|
||||
<string name="queryport">10543</string>
|
||||
<string name="httpport">10544</string>
|
||||
<color name="headlineColor">#333333</color>
|
||||
<string name="menu_controls">Player controls</string>
|
||||
<string name="menu_browse">Browse</string>
|
||||
</resources>
|
||||
|
@ -14,6 +14,9 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
@ -219,4 +222,26 @@ public class CategoryList extends ListActivity implements OnQueryResultListener
|
||||
startService(new Intent(this, org.musikcube.Service.class));
|
||||
}
|
||||
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.default_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.context_settings:
|
||||
startActivity(new Intent(this, org.musikcube.Preferences.class));
|
||||
return true;
|
||||
case R.id.context_browse:
|
||||
startActivity(new Intent(this, org.musikcube.main.class));
|
||||
return true;
|
||||
case R.id.context_controls:
|
||||
startActivity(new Intent(this, org.musikcube.PlayerControl.class));
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageButton;
|
||||
@ -219,4 +222,29 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener, On
|
||||
seconds+=0.1; updatecount();
|
||||
} }, 100, 100);
|
||||
*/
|
||||
|
||||
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.default_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.context_settings:
|
||||
startActivity(new Intent(this, org.musikcube.Preferences.class));
|
||||
return true;
|
||||
case R.id.context_browse:
|
||||
startActivity(new Intent(this, org.musikcube.main.class));
|
||||
return true;
|
||||
case R.id.context_controls:
|
||||
startActivity(new Intent(this, org.musikcube.PlayerControl.class));
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ public class Player implements TrackPlayer.OnTrackStatusListener{
|
||||
|
||||
private ArrayList<TrackPlayer> playingTracks = new ArrayList<TrackPlayer>();
|
||||
private TrackPlayer currentPlayer;
|
||||
private TrackPlayer nextPlayer;
|
||||
|
||||
public android.app.Service service;
|
||||
|
||||
@ -52,28 +53,56 @@ public class Player implements TrackPlayer.OnTrackStatusListener{
|
||||
this.Play();
|
||||
}
|
||||
|
||||
private TrackPlayer PrepareTrack(int position){
|
||||
synchronized(this.lock){
|
||||
if(this.nowPlaying.size()>position && position>=0){
|
||||
int trackId = this.nowPlaying.get(position);
|
||||
String url = "http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+trackId+"&auth_key="+this.library.authorization;
|
||||
TrackPlayer player = new TrackPlayer(url,trackId);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Play(){
|
||||
this.Startup();
|
||||
this.StopAllTracks();
|
||||
|
||||
|
||||
TrackPlayer newPlayer = null;
|
||||
synchronized(this.lock){
|
||||
String url = "http://"+this.library.host+":"+this.library.httpPort+"/track/?track_id="+this.nowPlaying.get(this.position)+"&auth_key="+this.library.authorization;
|
||||
TrackPlayer player = new TrackPlayer(url,true);
|
||||
player.listener = this;
|
||||
this.playingTracks.add(player);
|
||||
this.currentPlayer = player;
|
||||
|
||||
if(this.listener!=null){
|
||||
this.listener.OnTrackUpdate();
|
||||
this.listener.OnTrackBufferUpdate(0);
|
||||
this.listener.OnTrackPositionUpdate(0);
|
||||
if(this.nowPlaying.size()>position && position>=0){
|
||||
int trackId = this.nowPlaying.get(position);
|
||||
if(this.nextPlayer!=null){
|
||||
if(this.nextPlayer.trackId==trackId){
|
||||
newPlayer = this.nextPlayer;
|
||||
this.nextPlayer = null;
|
||||
}else{
|
||||
// Something wrong here, not the prepared track
|
||||
this.nextPlayer.Stop();
|
||||
this.nextPlayer = null;
|
||||
}
|
||||
}
|
||||
if(newPlayer==null){
|
||||
newPlayer = this.PrepareTrack(this.position);
|
||||
}
|
||||
this.playingTracks.add(newPlayer);
|
||||
this.currentPlayer = newPlayer;
|
||||
newPlayer.listener = this;
|
||||
newPlayer.Play();
|
||||
|
||||
if(this.listener!=null){
|
||||
this.listener.OnTrackUpdate();
|
||||
this.listener.OnTrackBufferUpdate(0);
|
||||
this.listener.OnTrackPositionUpdate(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// Inteface for updated track
|
||||
// Interface for updated track
|
||||
public interface OnTrackUpdateListener{
|
||||
public void OnTrackUpdate();
|
||||
public void OnTrackBufferUpdate(int percent);
|
||||
@ -147,10 +176,12 @@ public class Player implements TrackPlayer.OnTrackStatusListener{
|
||||
}
|
||||
|
||||
public void OnTrackStatusUpdate(TrackPlayer trackPlayer,int status) {
|
||||
// this.Next();
|
||||
Intent intent = new Intent(this.service, org.musikcube.Service.class);
|
||||
if(status==TrackPlayer.STATUS_EXIT){
|
||||
this.Next();
|
||||
}
|
||||
/* Intent intent = new Intent(this.service, org.musikcube.Service.class);
|
||||
intent.putExtra("org.musikcube.Service.action", "next");
|
||||
this.service.startService(intent);
|
||||
this.service.startService(intent);*/
|
||||
}
|
||||
|
||||
public int GetCurrentTrackId(){
|
||||
@ -183,4 +214,12 @@ public class Player implements TrackPlayer.OnTrackStatusListener{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void OnTrackAlmostDone(TrackPlayer trackPlayer) {
|
||||
synchronized(this.lock){
|
||||
if(this.nextPlayer==null){
|
||||
this.nextPlayer = this.PrepareTrack(this.position+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,18 +4,20 @@ import android.media.MediaPlayer;
|
||||
|
||||
public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,MediaPlayer.OnBufferingUpdateListener {
|
||||
|
||||
public int trackId = 0;
|
||||
private Thread thread;
|
||||
private String url;
|
||||
private java.lang.Object lock = new java.lang.Object();
|
||||
private MediaPlayer mediaPlayer;
|
||||
private int buffer = 0;
|
||||
private boolean almostDoneSend = false;
|
||||
|
||||
private int status = 1;
|
||||
|
||||
private static final int STATUS_PREPARED = 1;
|
||||
private static final int STATUS_PLAYING = 2;
|
||||
private static final int STATUS_PAUSE = 3;
|
||||
private static final int STATUS_EXIT = 10;
|
||||
public static final int STATUS_PREPARED = 1;
|
||||
public static final int STATUS_PLAYING = 2;
|
||||
public static final int STATUS_PAUSE = 3;
|
||||
public static final int STATUS_EXIT = 10;
|
||||
|
||||
public void run() {
|
||||
synchronized(this.lock){
|
||||
@ -44,37 +46,50 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
this.mediaPlayer.start();
|
||||
|
||||
synchronized(this.lock){
|
||||
while(this.status==STATUS_PLAYING)
|
||||
this.lock.wait();
|
||||
while(this.status==STATUS_PLAYING){
|
||||
if(!this.almostDoneSend){
|
||||
int duration = this.mediaPlayer.getDuration();
|
||||
int position = this.mediaPlayer.getCurrentPosition();
|
||||
if(duration>0 && position+10000>duration){
|
||||
// The track is almost done
|
||||
this.almostDoneSend = true;
|
||||
if(this.listener!=null){
|
||||
this.listener.OnTrackAlmostDone(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.lock.wait(3000);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.mediaPlayer.stop();
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
synchronized(this.lock){
|
||||
this.status = STATUS_EXIT;
|
||||
}
|
||||
}
|
||||
synchronized(this.lock){
|
||||
this.status = STATUS_EXIT;
|
||||
}
|
||||
|
||||
this.CallListener();
|
||||
|
||||
}
|
||||
|
||||
public TrackPlayer(String url){
|
||||
public TrackPlayer(String url,int trackId){
|
||||
this.trackId = trackId;
|
||||
this.url = url;
|
||||
this.thread = new Thread(this);
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
public TrackPlayer(String url,boolean start){
|
||||
/* public TrackPlayer(String url,boolean start){
|
||||
this.url = url;
|
||||
if(start==true){
|
||||
this.status = STATUS_PLAYING;
|
||||
}
|
||||
this.thread = new Thread(this);
|
||||
this.thread.start();
|
||||
}
|
||||
}*/
|
||||
|
||||
private void Exit(){
|
||||
synchronized(this.lock){
|
||||
@ -101,15 +116,13 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
}
|
||||
}
|
||||
|
||||
public boolean Play(){
|
||||
public void Play(){
|
||||
synchronized(this.lock){
|
||||
if(this.status==STATUS_PLAYING || this.status==STATUS_PREPARED){
|
||||
this.status = STATUS_PLAYING;
|
||||
this.lock.notifyAll();
|
||||
return true;
|
||||
}
|
||||
this.lock.notifyAll();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CallListener(){
|
||||
@ -126,6 +139,7 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
|
||||
public interface OnTrackStatusListener{
|
||||
public void OnTrackStatusUpdate(TrackPlayer trackPlayer,int status);
|
||||
public void OnTrackAlmostDone(TrackPlayer trackPlayer);
|
||||
}
|
||||
|
||||
public OnTrackStatusListener listener = null;
|
||||
|
@ -68,10 +68,15 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.context_settings:
|
||||
Intent intent = new Intent(main.this, Preferences.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.context_settings:
|
||||
startActivity(new Intent(this, org.musikcube.Preferences.class));
|
||||
return true;
|
||||
case R.id.context_browse:
|
||||
startActivity(new Intent(this, org.musikcube.main.class));
|
||||
return true;
|
||||
case R.id.context_controls:
|
||||
startActivity(new Intent(this, org.musikcube.PlayerControl.class));
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user