/*****************************************************************************
* AudioMiniPlayer.java
*****************************************************************************
* Copyright © 2011-2012 VLC authors and VideoLAN
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
package org.videolan.vlc.gui.audio;
import java.util.ArrayList;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.vlc.AudioServiceController;
import org.videolan.vlc.RepeatType;
import org.videolan.vlc.Util;
import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.gui.CommonDialogs.MenuType;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.interfaces.IAudioPlayer;
import org.videolan.vlc.widget.AnimatedCoverView;
import org.videolan.vlc.widget.AudioMediaSwitcher;
import org.videolan.vlc.widget.AudioMediaSwitcher.AudioMediaSwitcherListener;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import org.tribler.triblersvod.gui.R;
public class AudioPlayer extends Fragment implements IAudioPlayer {
public static final String TAG = "VLC/AudioMiniPlayer";
private ProgressBar mProgressBar;
private AudioMediaSwitcher mAudioMediaSwitcher;
private AnimatedCoverView mBigCover;
private TextView mTime;
private TextView mHeaderTime;
private TextView mLength;
private ImageButton mPlayPause;
private ImageButton mHeaderPlayPause;
private ImageButton mNext;
private ImageButton mPrevious;
private ImageButton mShuffle;
private ImageButton mRepeat;
private ImageButton mAdvFunc;
private ImageButton mPlaylistSwitch;
private SeekBar mTimeline;
private AudioPlaylistView mSongsList;
ViewSwitcher mSwitcher;
private AudioServiceController mAudioController;
private boolean mShowRemainingTime = false;
private AudioListAdapter mSongsListAdapter;
private boolean mAdvFuncVisible;
private boolean mPlaylistSwitchVisible;
private boolean mHeaderPlayPauseVisible;
private boolean mProgressBarVisible;
private boolean mHeaderTimeVisible;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAudioController = AudioServiceController.getInstance();
mSongsListAdapter = new AudioListAdapter(getActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.audio_player, container, false);
mProgressBar = (ProgressBar) v.findViewById(R.id.progressBar);
mAudioMediaSwitcher = (AudioMediaSwitcher) v.findViewById(R.id.audio_media_switcher);
mAudioMediaSwitcher.setAudioMediaSwitcherListener(mAudioMediaSwitcherListener);
mBigCover = (AnimatedCoverView) v.findViewById(R.id.big_cover);
mTime = (TextView) v.findViewById(R.id.time);
mHeaderTime = (TextView) v.findViewById(R.id.header_time);
mLength = (TextView) v.findViewById(R.id.length);
mPlayPause = (ImageButton) v.findViewById(R.id.play_pause);
mHeaderPlayPause = (ImageButton) v.findViewById(R.id.header_play_pause);
mNext = (ImageButton) v.findViewById(R.id.next);
mPrevious = (ImageButton) v.findViewById(R.id.previous);
mShuffle = (ImageButton) v.findViewById(R.id.shuffle);
mRepeat = (ImageButton) v.findViewById(R.id.repeat);
mAdvFunc = (ImageButton) v.findViewById(R.id.adv_function);
mPlaylistSwitch = (ImageButton) v.findViewById(R.id.playlist_switch);
mTimeline = (SeekBar) v.findViewById(R.id.timeline);
mSongsList = (AudioPlaylistView) v.findViewById(R.id.songs_list);
mSongsList.setAdapter(mSongsListAdapter);
mSwitcher = (ViewSwitcher) v.findViewById(R.id.view_switcher);
mSwitcher.setInAnimation(getActivity(), android.R.anim.fade_in);
mSwitcher.setOutAnimation(getActivity(), android.R.anim.fade_out);
mAdvFuncVisible = false;
mPlaylistSwitchVisible = false;
mHeaderPlayPauseVisible = true;
mProgressBarVisible = true;
mHeaderTimeVisible = true;
restoreHedaderButtonVisibilities();
mTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onTimeLabelClick(v);
}
});
mPlayPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPlayPauseClick(v);
}
});
mPlayPause.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
onStopClick(v);
return true;
}
});
mHeaderPlayPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPlayPauseClick(v);
}
});
mNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onNextClick(v);
}
});
mPrevious.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPreviousClick(v);
}
});
mShuffle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onShuffleClick(v);
}
});
mRepeat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onRepeatClick(v);
}
});
mAdvFunc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showAdvancedOptions(v);
}
});
mPlaylistSwitch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSwitcher.showNext();
if (mSwitcher.getDisplayedChild() == 0)
mPlaylistSwitch.setImageResource(R.drawable.ic_playlist_switch_glow);
else
mPlaylistSwitch.setImageResource(R.drawable.ic_playlist_switch);
}
});
mSongsList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
mAudioController.load(mSongsListAdapter.getLocations(), p);
}
});
mSongsList.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
getActivity().openContextMenu(view);
return true;
}
});
mSongsList.setOnItemDraggedListener(new AudioPlaylistView.OnItemDraggedListener() {
@Override
public void OnItemDradded(int positionStart, int positionEnd) {
mAudioController.moveItem(positionStart, positionEnd);
}
});
mSongsList.setOnItemRemovedListener(new AudioPlaylistView.OnItemRemovedListener() {
@Override
public void onItemRemoved(int position) {
mAudioController.remove(position);
}
});
registerForContextMenu(mSongsList);
getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
return v;
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
MenuInflater menuInflater = getActivity().getMenuInflater();
menuInflater.inflate(R.menu.audio_player, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
if(info == null) // info can be null
return super.onContextItemSelected(item);
int id = item.getItemId();
if(id == R.id.audio_player_mini_remove) {
Log.d(TAG, "Context menu removing " + info.position);
mAudioController.remove(info.position);
return true;
}
return super.onContextItemSelected(item);
}
/**
* Show the audio player from an intent
*
* @param context The context of the activity
*/
public static void start(Context context) {
Intent intent = new Intent();
intent.setAction(MainActivity.ACTION_SHOW_PLAYER);
context.getApplicationContext().sendBroadcast(intent);
}
@Override
public synchronized void update() {
if (mAudioController == null)
return;
if (mAudioController.hasMedia()) {
show();
} else {
hide();
return;
}
Bitmap cover = mAudioController.getCover();
if (cover == null)
cover = BitmapFactory.decodeResource(getResources(), R.drawable.cone);
mBigCover.setImageBitmap(cover);
mAudioMediaSwitcher.updateMedia();
if (mAudioController.isPlaying()) {
mPlayPause.setImageResource(R.drawable.ic_pause);
mPlayPause.setContentDescription(getString(R.string.pause));
mHeaderPlayPause.setImageResource(R.drawable.ic_pause);
mHeaderPlayPause.setContentDescription(getString(R.string.pause));
} else {
mPlayPause.setImageResource(R.drawable.ic_play);
mPlayPause.setContentDescription(getString(R.string.play));
mHeaderPlayPause.setImageResource(R.drawable.ic_play);
mHeaderPlayPause.setContentDescription(getString(R.string.play));
}
if (mAudioController.isShuffling()) {
mShuffle.setImageResource(R.drawable.ic_shuffle_glow);
} else {
mShuffle.setImageResource(R.drawable.ic_shuffle);
}
switch(mAudioController.getRepeatType()) {
case None:
mRepeat.setImageResource(R.drawable.ic_repeat);
break;
case Once:
mRepeat.setImageResource(R.drawable.ic_repeat_one);
break;
default:
case All:
mRepeat.setImageResource(R.drawable.ic_repeat_glow);
break;
}
if (mAudioController.hasNext())
mNext.setVisibility(ImageButton.VISIBLE);
else
mNext.setVisibility(ImageButton.INVISIBLE);
if (mAudioController.hasPrevious())
mPrevious.setVisibility(ImageButton.VISIBLE);
else
mPrevious.setVisibility(ImageButton.INVISIBLE);
mTimeline.setOnSeekBarChangeListener(mTimelineListner);
updateList();
}
@Override
public synchronized void updateProgress() {
int time = mAudioController.getTime();
int length = mAudioController.getLength();
mTime.setText(Util.millisToString(mShowRemainingTime ? time-length : time));
mHeaderTime.setText(Util.millisToString(time));
mLength.setText(Util.millisToString(length));
mTimeline.setMax(length);
mTimeline.setProgress(time);
mProgressBar.setMax(length);
mProgressBar.setProgress(time);
}
private void updateList() {
ArrayList<Media> audioList = new ArrayList<Media>();
String currentItem = null;
int currentIndex = -1;
LibVLC libVLC = LibVLC.getExistingInstance();
for (int i = 0; i < libVLC.getMediaList().size(); i++) {
audioList.add(libVLC.getMediaList().getMedia(i));
}
currentItem = mAudioController.getCurrentMediaLocation();
mSongsListAdapter.clear();
for (int i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
if (currentItem != null && currentItem.equals(media.getLocation()))
currentIndex = i;
mSongsListAdapter.add(media);
}
mSongsListAdapter.setCurrentIndex(currentIndex);
mSongsList.setSelection(currentIndex);
mSongsListAdapter.notifyDataSetChanged();
}
OnSeekBarChangeListener mTimelineListner = new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar sb, int prog, boolean fromUser) {
if (fromUser) {
mAudioController.setTime(prog);
mTime.setText(Util.millisToString(mShowRemainingTime ? prog-mAudioController.getLength() : prog));
mHeaderTime.setText(Util.millisToString(prog));
}
}
};
public void onTimeLabelClick(View view) {
mShowRemainingTime = !mShowRemainingTime;
update();
}
public void onPlayPauseClick(View view) {
if (mAudioController.isPlaying()) {
mAudioController.pause();
} else {
mAudioController.play();
}
}
public void onStopClick(View view) {
mAudioController.stop();
}
public void onNextClick(View view) {
mAudioController.next();
}
public void onPreviousClick(View view) {
mAudioController.previous();
}
public void onRepeatClick(View view) {
switch (mAudioController.getRepeatType()) {
case None:
mAudioController.setRepeatType(RepeatType.All);
break;
case All:
mAudioController.setRepeatType(RepeatType.Once);
break;
default:
case Once:
mAudioController.setRepeatType(RepeatType.None);
break;
}
update();
}
public void onShuffleClick(View view) {
mAudioController.shuffle();
update();
}
public void showAdvancedOptions(View v) {
CommonDialogs.advancedOptions(getActivity(), v, MenuType.Audio);
}
public void show() {
MainActivity activity = (MainActivity)getActivity();
activity.showAudioPlayer();
}
public void hide() {
MainActivity activity = (MainActivity)getActivity();
activity.hideAudioPlayer();
}
/**
* Set the visibilities of the player header elements.
* @param advFuncVisible
* @param playlistSwitchVisible
* @param headerPlayPauseVisible
*/
public void setHeaderVisibilities(boolean advFuncVisible, boolean playlistSwitchVisible,
boolean headerPlayPauseVisible, boolean progressBarVisible,
boolean headerTimeVisible) {
mAdvFuncVisible = advFuncVisible;
mPlaylistSwitchVisible = playlistSwitchVisible;
mHeaderPlayPauseVisible = headerPlayPauseVisible;
mProgressBarVisible = progressBarVisible;
mHeaderTimeVisible = headerTimeVisible;
restoreHedaderButtonVisibilities();
}
private void restoreHedaderButtonVisibilities() {
mAdvFunc.setVisibility(mAdvFuncVisible ? ImageButton.VISIBLE : ImageButton.GONE);
mPlaylistSwitch.setVisibility(mPlaylistSwitchVisible ? ImageButton.VISIBLE : ImageButton.GONE);
mHeaderPlayPause.setVisibility(mHeaderPlayPauseVisible ? ImageButton.VISIBLE : ImageButton.GONE);
mProgressBar.setVisibility(mProgressBarVisible ? ProgressBar.VISIBLE : ProgressBar.GONE);
mHeaderTime.setVisibility(mHeaderTimeVisible ? TextView.VISIBLE : TextView.GONE);
}
private void hideHedaderButtons() {
mAdvFunc.setVisibility(ImageButton.GONE);
mPlaylistSwitch.setVisibility(ImageButton.GONE);
mHeaderPlayPause.setVisibility(ImageButton.GONE);
mHeaderTime.setVisibility(TextView.GONE);
}
private final AudioMediaSwitcherListener mAudioMediaSwitcherListener = new AudioMediaSwitcherListener() {
@Override
public void onMediaSwitching() {}
@Override
public void onMediaSwitched(int position) {
if (position == AudioMediaSwitcherListener.PREVIOUS_MEDIA)
mAudioController.previous();
else if (position == AudioMediaSwitcherListener.NEXT_MEDIA)
mAudioController.next();
}
@Override
public void onTouchDown() {
hideHedaderButtons();
}
@Override
public void onTouchUp() {
restoreHedaderButtonVisibilities();
}
};
}