/*****************************************************************************
* MediaWrapper.java
*****************************************************************************
* Copyright © 2011-2015 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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;
import java.io.File;
import java.util.Locale;
import org.videolan.libvlc.MediaPlayer;
import org.videolan.libvlc.util.AndroidUtil;
import org.videolan.libvlc.util.Extensions;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.Media.VideoTrack;
import org.videolan.libvlc.Media.Meta;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
public class MediaWrapper implements Parcelable {
public final static String TAG = "VLC/MediaWrapper";
public final static int TYPE_ALL = -1;
public final static int TYPE_VIDEO = 0;
public final static int TYPE_AUDIO = 1;
public final static int TYPE_GROUP = 2;
public final static int TYPE_DIR = 3;
public final static int TYPE_SUBTITLE = 4;
public final static int TYPE_PLAYLIST = 5;
public final static int MEDIA_VIDEO = 0x01;
public final static int MEDIA_NO_HWACCEL = 0x02;
public final static int MEDIA_PAUSED = 0x4;
public final static int MEDIA_FORCE_AUDIO = 0x8;
protected String mTitle;
private String mArtist;
private String mGenre;
private String mCopyright;
private String mAlbum;
private int mTrackNumber;
private int mDiscNumber;
private String mAlbumArtist;
private String mDescription;
private String mRating;
private String mDate;
private String mSettings;
private String mNowPlaying;
private String mPublisher;
private String mEncodedBy;
private String mTrackID;
private String mArtworkURL;
private final Uri mUri;
private String mFilename;
private long mTime = 0;
/* -1 is a valid track (Disabled) */
private int mAudioTrack = -2;
private int mSpuTrack = -2;
private long mLength = 0;
private int mType;
private int mWidth = 0;
private int mHeight = 0;
private Bitmap mPicture;
private boolean mIsPictureParsed;
private int mFlags = 0;
private long mLastModified = 0l;
/**
* Create a new MediaWrapper
* @param uri Should not be null.
*/
public MediaWrapper(Uri uri) {
if (uri == null)
throw new NullPointerException("uri was null");
mUri = uri;
init(null);
}
/**
* Create a new MediaWrapper
* @param media should be parsed and not NULL
*/
public MediaWrapper(Media media) {
if (media == null)
throw new NullPointerException("media was null");
mUri = media.getUri();
init(media);
}
@Override
public boolean equals(Object obj) {
if (mUri == ((MediaWrapper)obj).getUri())
return true;
return false;
}
private void init(Media media) {
mType = TYPE_ALL;
if (media != null) {
if (media.isParsed()) {
mLength = media.getDuration();
for (int i = 0; i < media.getTrackCount(); ++i) {
final Media.Track track = media.getTrack(i);
if (track == null)
continue;
if (track.type == Media.Track.Type.Video) {
final Media.VideoTrack videoTrack = (VideoTrack) track;
mType = TYPE_VIDEO;
mWidth = videoTrack.width;
mHeight = videoTrack.height;
} else if (mType == TYPE_ALL && track.type == Media.Track.Type.Audio){
mType = TYPE_AUDIO;
}
}
}
updateMeta(media);
if (mType == TYPE_ALL && media.getType() == Media.Type.Directory)
mType = TYPE_DIR;
}
if (mType == TYPE_ALL) {
final int index = mUri.toString().indexOf('?');
String location;
if (index == -1)
location = mUri.toString();
else
location = mUri.toString().substring(0, index);
int dotIndex = location.lastIndexOf(".");
if (dotIndex != -1) {
String fileExt = location.substring(dotIndex).toLowerCase(Locale.ENGLISH);
if( Extensions.VIDEO.contains(fileExt) ) {
mType = TYPE_VIDEO;
} else if (Extensions.AUDIO.contains(fileExt)) {
mType = TYPE_AUDIO;
} else if (Extensions.SUBTITLES.contains(fileExt)) {
mType = TYPE_SUBTITLE;
} else if (Extensions.PLAYLIST.contains(fileExt)) {
mType = TYPE_PLAYLIST;
}
}
}
}
private void init(long time, long length, int type,
Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
int width, int height, String artworkURL, int audio, int spu, int trackNumber, int discNumber, long lastModified) {
mFilename = null;
mTime = time;
mAudioTrack = audio;
mSpuTrack = spu;
mLength = length;
mType = type;
mPicture = picture;
mWidth = width;
mHeight = height;
mTitle = title;
mArtist = artist;
mGenre = genre;
mAlbum = album;
mAlbumArtist = albumArtist;
mArtworkURL = artworkURL;
mTrackNumber = trackNumber;
mDiscNumber = discNumber;
mLastModified = lastModified;
}
public MediaWrapper(Uri uri, long time, long length, int type,
Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
int width, int height, String artworkURL, int audio, int spu, int trackNumber, int discNumber, long lastModified) {
mUri = uri;
init(time, length, type, picture, title, artist, genre, album, albumArtist,
width, height, artworkURL, audio, spu, trackNumber, discNumber, lastModified);
}
public String getLocation() {
return mUri.toString();
}
public Uri getUri() {
return mUri;
}
private static String getMetaId(Media media, int id, boolean trim) {
String meta = media.getMeta(id);
return meta != null ? trim ? meta.trim() : meta : null;
}
public void updateMeta(Media media) {
mTitle = getMetaId(media, Meta.Title, true);
mArtist = getMetaId(media, Meta.Artist, true);
mAlbum = getMetaId(media, Meta.Album, true);
mGenre = getMetaId(media, Meta.Genre, true);
mAlbumArtist = getMetaId(media, Meta.AlbumArtist, true);
mArtworkURL = getMetaId(media, Meta.ArtworkURL, false);
mNowPlaying = getMetaId(media, Meta.NowPlaying, false);
final String trackNumber = getMetaId(media, Meta.TrackNumber, false);
if (!TextUtils.isEmpty(trackNumber)) {
try {
mTrackNumber = Integer.parseInt(trackNumber);
} catch (NumberFormatException ignored) {}
}
final String discNumber = getMetaId(media, Meta.DiscNumber, false);
if (!TextUtils.isEmpty(discNumber)) {
try {
mDiscNumber = Integer.parseInt(discNumber);
} catch (NumberFormatException ignored) {}
}
Log.d(TAG, "Title " + mTitle);
Log.d(TAG, "Artist " + mArtist);
Log.d(TAG, "Genre " + mGenre);
Log.d(TAG, "Album " + mAlbum);
}
public void updateMeta(MediaPlayer mediaPlayer) {
final Media media = mediaPlayer.getMedia();
if (media == null)
return;
updateMeta(media);
media.release();
}
public String getFileName() {
if (mFilename == null) {
mFilename = mUri.getLastPathSegment();
}
return mFilename;
}
public long getTime() {
return mTime;
}
public void setTime(long time) {
mTime = time;
}
public int getAudioTrack() {
return mAudioTrack;
}
public void setAudioTrack(int track) {
mAudioTrack = track;
}
public int getSpuTrack() {
return mSpuTrack;
}
public void setSpuTrack(int track) {
mSpuTrack = track;
}
public long getLength() {
return mLength;
}
public int getType() {
return mType;
}
public void setType(int type){
mType = type;
}
public int getWidth() {
return mWidth;
}
public int getHeight() {
return mHeight;
}
/**
* Returns the raw picture object. Likely to be NULL in VLC for Android
* due to lazy-loading.
*
* Use {@link org.videolan.vlc.util.BitmapUtil#getPictureFromCache(MediaWrapper)} instead.
*
* @return The raw picture or NULL
*/
public Bitmap getPicture() {
return mPicture;
}
/**
* Sets the raw picture object.
*
* In VLC for Android, use {@link org.videolan.vlc.MediaDatabase#setPicture(MediaWrapper, Bitmap)} instead.
*
* @param p
*/
public void setPicture(Bitmap p) {
mPicture = p;
}
public boolean isPictureParsed() {
return mIsPictureParsed;
}
public void setPictureParsed(boolean isParsed) {
mIsPictureParsed = isParsed;
}
public void setTitle(String title){
mTitle = title;
}
public String getTitle() {
if (!TextUtils.isEmpty(mTitle))
return mTitle;
else {
String fileName = getFileName();
if (fileName == null)
return "";
int end = fileName.lastIndexOf(".");
if (end <= 0)
return fileName;
return fileName.substring(0, end);
}
}
public String getDisplayTitle() {
return getTitle();
}
public String getReferenceArtist() {
return mAlbumArtist == null ? mArtist : mAlbumArtist;
}
public String getArtist() {
return mArtist;
}
public Boolean isArtistUnknown() {
return mArtist == null;
}
public String getGenre() {
if (mGenre == null)
return null;
else if (mGenre.length() > 1)/* Make genres case insensitive via normalisation */
return Character.toUpperCase(mGenre.charAt(0)) + mGenre.substring(1).toLowerCase(Locale.getDefault());
else
return mGenre;
}
public String getCopyright() {
return mCopyright;
}
public String getAlbum() {
return mAlbum;
}
public String getAlbumArtist() {
return mAlbumArtist;
}
public Boolean isAlbumUnknown() {
return mAlbum == null;
}
public int getTrackNumber() {
return mTrackNumber;
}
public int getDiscNumber() {
return mDiscNumber;
}
public void setDescription(String description){
mDescription = description;
}
public String getDescription() {
return mDescription;
}
public String getRating() {
return mRating;
}
public String getDate() {
return mDate;
}
public String getSettings() {
return mSettings;
}
public String getNowPlaying() {
return mNowPlaying;
}
public String getPublisher() {
return mPublisher;
}
public String getEncodedBy() {
return mEncodedBy;
}
public String getTrackID() {
return mTrackID;
}
public String getArtworkURL() {
return mArtworkURL;
}
public long getLastModified() {
return mLastModified;
}
public void setLastModified(long mLastModified) {
this.mLastModified = mLastModified;
}
public void addFlags(int flags) {
mFlags |= flags;
}
public void setFlags(int flags) {
mFlags = flags;
}
public int getFlags() {
return mFlags;
}
public void removeFlags(int flags) {
mFlags &= ~flags;
}
@Override
public int describeContents() {
return 0;
}
public MediaWrapper(Parcel in) {
mUri = in.readParcelable(Uri.class.getClassLoader());
init(in.readLong(),
in.readLong(),
in.readInt(),
(Bitmap) in.readParcelable(Bitmap.class.getClassLoader()),
in.readString(),
in.readString(),
in.readString(),
in.readString(),
in.readString(),
in.readInt(),
in.readInt(),
in.readString(),
in.readInt(),
in.readInt(),
in.readInt(),
in.readInt(),
in.readLong());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(mUri, flags);
dest.writeLong(getTime());
dest.writeLong(getLength());
dest.writeInt(getType());
dest.writeParcelable(getPicture(), flags);
dest.writeString(getTitle());
dest.writeString(getArtist());
dest.writeString(getGenre());
dest.writeString(getAlbum());
dest.writeString(getAlbumArtist());
dest.writeInt(getWidth());
dest.writeInt(getHeight());
dest.writeString(getArtworkURL());
dest.writeInt(getAudioTrack());
dest.writeInt(getSpuTrack());
dest.writeInt(getTrackNumber());
dest.writeInt(getDiscNumber());
dest.writeLong(getLastModified());
}
public static final Parcelable.Creator<MediaWrapper> CREATOR = new Parcelable.Creator<MediaWrapper>() {
public MediaWrapper createFromParcel(Parcel in) {
return new MediaWrapper(in);
}
public MediaWrapper[] newArray(int size) {
return new MediaWrapper[size];
}
};
}