Widevine sample player
For bug 4245169 Change-Id: Ie110d5603f19cd54878d2c4506e8ffad11207f10
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Button;
|
||||
|
||||
public abstract class AssetActivity extends Activity {
|
||||
|
||||
private int currentPage;
|
||||
protected ArrayList<AssetsPage> pages;
|
||||
private Context context;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
context = this;
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
currentPage = 0;
|
||||
|
||||
pages = new ArrayList<AssetsPage>();
|
||||
|
||||
if (setUpAssetPages()) {
|
||||
setContentView(createView(this));
|
||||
} else {
|
||||
setContentView(R.layout.empty);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean setUpAssetPages();
|
||||
|
||||
private View createView(Context ctxt) {
|
||||
|
||||
ImageView empty = new ImageView(this);
|
||||
empty.setBackgroundDrawable(getResources().getDrawable(R.drawable.empty));
|
||||
|
||||
View[] clips = new View[6];
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inDither = true;
|
||||
|
||||
AssetsPage page = pages.get(currentPage);
|
||||
|
||||
for (int i = 0; i < page.getPageCount(); i++) {
|
||||
|
||||
AssetItem assetItem = page.getPage(i);
|
||||
clips[i] = createViewItem(getBitmapFromAssetItem(assetItem), assetItem.getAssetPath(),
|
||||
assetItem.getTitle());
|
||||
|
||||
}
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.FILL_PARENT, 1);
|
||||
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
|
||||
|
||||
LinearLayout.LayoutParams paramsMain = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.FILL_PARENT, 1);
|
||||
paramsMain.gravity = Gravity.CENTER;
|
||||
|
||||
LinearLayout left = new LinearLayout(ctxt);
|
||||
left.setOrientation(LinearLayout.VERTICAL);
|
||||
if (clips[0] != null) {
|
||||
left.addView(clips[0], params);
|
||||
}
|
||||
if (clips[3] != null) {
|
||||
left.addView(clips[3], params);
|
||||
} else {
|
||||
left.addView(createEmptyView(), params);
|
||||
}
|
||||
|
||||
LinearLayout middle = new LinearLayout(ctxt);
|
||||
middle.setOrientation(LinearLayout.VERTICAL);
|
||||
if (clips[1] != null) {
|
||||
middle.addView(clips[1], params);
|
||||
}
|
||||
if (clips[4] != null) {
|
||||
middle.addView(clips[4], params);
|
||||
} else {
|
||||
middle.addView(createEmptyView(), params);
|
||||
}
|
||||
|
||||
LinearLayout right = new LinearLayout(ctxt);
|
||||
right.setOrientation(LinearLayout.VERTICAL);
|
||||
if (clips[2] != null) {
|
||||
right.addView(clips[2], params);
|
||||
}
|
||||
params.gravity = Gravity.BOTTOM;
|
||||
if (clips[5] != null) {
|
||||
right.addView(clips[5], params);
|
||||
} else {
|
||||
right.addView(createEmptyView(), params);
|
||||
}
|
||||
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
|
||||
|
||||
LinearLayout body = new LinearLayout(ctxt);
|
||||
|
||||
body.addView(left, paramsMain);
|
||||
body.addView(middle, paramsMain);
|
||||
body.addView(right, paramsMain);
|
||||
|
||||
// Next button listener
|
||||
View.OnClickListener nextButtonListener = new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
currentPage++;
|
||||
if (currentPage >= pages.size()) {
|
||||
currentPage = 0;
|
||||
}
|
||||
setContentView(createView(context));
|
||||
}
|
||||
};
|
||||
|
||||
Button next = new Button(this);
|
||||
next.setText(">>");
|
||||
next.setOnClickListener(nextButtonListener);
|
||||
|
||||
// Previous button listener
|
||||
View.OnClickListener prevButtonListener = new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
|
||||
currentPage--;
|
||||
if (currentPage < 0) {
|
||||
currentPage = pages.size() - 1;
|
||||
}
|
||||
setContentView(createView(context));
|
||||
|
||||
}
|
||||
};
|
||||
Button prev = new Button(this);
|
||||
prev.setText("<<");
|
||||
prev.setOnClickListener(prevButtonListener);
|
||||
|
||||
LinearLayout buttons = new LinearLayout(this);
|
||||
buttons.addView(prev, params);
|
||||
buttons.addView(next, params);
|
||||
|
||||
body.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.background3));
|
||||
|
||||
SwipeLinearLayout main = new SwipeLinearLayout(this);
|
||||
main.setNext(nextButtonListener);
|
||||
main.setPrev(prevButtonListener);
|
||||
main.setOrientation(LinearLayout.VERTICAL);
|
||||
main.addView(body, params);
|
||||
|
||||
LinearLayout.LayoutParams paramButtons = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
paramButtons.gravity = Gravity.CENTER;
|
||||
|
||||
main.addView(buttons, paramButtons);
|
||||
return main;
|
||||
}
|
||||
|
||||
private View createEmptyView() {
|
||||
ImageView empty = new ImageView(this);
|
||||
empty.setBackgroundDrawable(getResources().getDrawable(R.drawable.empty));
|
||||
|
||||
TextView emptyText = new TextView(this);
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
|
||||
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
|
||||
LinearLayout body = new LinearLayout(this);
|
||||
|
||||
body.setOrientation(LinearLayout.VERTICAL);
|
||||
body.addView(empty, params);
|
||||
|
||||
body.addView(emptyText, params);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
private View createViewItem(Bitmap image, String path, String title) {
|
||||
|
||||
final String assetPath = path;
|
||||
|
||||
ClipImageView clip = new ClipImageView(this);
|
||||
|
||||
clip.setImageBitmap(image);
|
||||
|
||||
// Set the onClick listener for each image
|
||||
clip.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, VideoPlayerView.class);
|
||||
intent.putExtra("com.widevine.demo.Path", assetPath);
|
||||
context.startActivity(intent);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
TextView text = new TextView(this);
|
||||
text.setText((title == null) ? path : title);
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
|
||||
params.gravity = Gravity.CENTER;
|
||||
LinearLayout body = new LinearLayout(this);
|
||||
|
||||
body.setOrientation(LinearLayout.VERTICAL);
|
||||
body.addView(clip, params);
|
||||
|
||||
body.addView(text, params);
|
||||
|
||||
return body;
|
||||
|
||||
}
|
||||
|
||||
private Bitmap getBitmapFromAssetItem(AssetItem assetItem) {
|
||||
Bitmap clipImage = null;
|
||||
String imageUrl = null;
|
||||
|
||||
if (assetItem.getImagePath() == null || assetItem.getImagePath().equals("")) {
|
||||
if (assetItem.getAssetPath().indexOf("http") == -1)
|
||||
clipImage = BitmapFactory.decodeResource(getResources(), R.drawable.download_clip);
|
||||
else
|
||||
clipImage = BitmapFactory.decodeResource(getResources(), R.drawable.streaming_clip);
|
||||
} else {
|
||||
InputStream bitmapStream = null;
|
||||
if (assetItem.getAssetPath().indexOf("http") != -1) {
|
||||
|
||||
imageUrl = assetItem.getImagePath();
|
||||
if (imageUrl != null) {
|
||||
ImageHandler imageHandler = new ImageHandler(imageUrl);
|
||||
imageHandler.start();
|
||||
try {
|
||||
imageHandler.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
clipImage = imageHandler.getBitmap();
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
bitmapStream = new FileInputStream(assetItem.getImagePath());
|
||||
} catch (FileNotFoundException e) {
|
||||
bitmapStream = null;
|
||||
}
|
||||
|
||||
clipImage = BitmapFactory.decodeStream(bitmapStream);
|
||||
}
|
||||
|
||||
if (clipImage == null) {
|
||||
clipImage = BitmapFactory.decodeResource(getResources(), R.drawable.streaming_clip);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return clipImage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
/**
|
||||
* Describes one asset in the list view
|
||||
*/
|
||||
public class AssetDescriptor {
|
||||
private String mThumbnail;
|
||||
private String mTitle;
|
||||
private String mDescription;
|
||||
private String mUri;
|
||||
private String mStatus;
|
||||
|
||||
public AssetDescriptor copy() {
|
||||
AssetDescriptor ad = new AssetDescriptor();
|
||||
ad.setTitle(mTitle);
|
||||
ad.setThumbnail(mThumbnail);
|
||||
ad.setDescription(mDescription);
|
||||
ad.setUri(mUri);
|
||||
return ad;
|
||||
}
|
||||
|
||||
public String getThumbnail() {
|
||||
return mThumbnail;
|
||||
}
|
||||
|
||||
public void setThumbnail(String thumbnail) {
|
||||
mThumbnail = thumbnail;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
mDescription = description;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
mStatus = status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
public class AssetItem {
|
||||
private String assetPath;
|
||||
private String imagePath;
|
||||
private String title;
|
||||
|
||||
public AssetItem() {
|
||||
assetPath = null;
|
||||
imagePath = null;
|
||||
title = null;
|
||||
}
|
||||
|
||||
public AssetItem(String assetPath, String imagePath, String title) {
|
||||
this.assetPath = assetPath;
|
||||
this.imagePath = imagePath;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAssetPath() {
|
||||
return assetPath;
|
||||
}
|
||||
|
||||
public String getImagePath() {
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AssetsPage {
|
||||
public static final int MAX_ITEMS = 6;
|
||||
|
||||
private ArrayList<AssetItem> assets;
|
||||
|
||||
public AssetsPage() {
|
||||
assets = new ArrayList<AssetItem>();
|
||||
}
|
||||
|
||||
public void addPage(String assetPath, String imagePath, String title) {
|
||||
assets.add(new AssetItem(assetPath, imagePath, title));
|
||||
}
|
||||
|
||||
public AssetItem getPage(int pageNumber) {
|
||||
return assets.get(pageNumber);
|
||||
}
|
||||
|
||||
public int getPageCount() {
|
||||
return assets.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import android.widget.ImageView;
|
||||
import android.view.MotionEvent;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
|
||||
public class ClipImageView extends ImageView {
|
||||
|
||||
private boolean touchedDown;
|
||||
private float touchX, touchY, radius;
|
||||
private boolean radiusInc;
|
||||
|
||||
private Bitmap selectCircle;
|
||||
|
||||
public ClipImageView(Context ctxt) {
|
||||
super(ctxt);
|
||||
|
||||
touchedDown = false;
|
||||
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inDither = true;
|
||||
selectCircle = BitmapFactory.decodeResource(getResources(), R.drawable.selection_circle,
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
|
||||
if (e.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
touchX = e.getX();
|
||||
touchY = e.getY();
|
||||
radius = 60;
|
||||
radiusInc = false;
|
||||
touchedDown = true;
|
||||
|
||||
} else if (e.getAction() == MotionEvent.ACTION_UP) {
|
||||
touchedDown = false;
|
||||
|
||||
}
|
||||
// return true;
|
||||
return super.onTouchEvent(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (touchedDown) {
|
||||
canvas.drawBitmap(selectCircle, null, new Rect((int) (touchX - radius),
|
||||
(int) (touchY - radius), (int) (touchX + radius),
|
||||
(int) (touchY + radius)), null);
|
||||
if (radiusInc) {
|
||||
radius += 5;
|
||||
}
|
||||
else {
|
||||
radius -= 5;
|
||||
}
|
||||
if (radius >= 60 || radius <= 0) {
|
||||
radiusInc = !radiusInc;
|
||||
}
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.sax.Element;
|
||||
import android.sax.EndElementListener;
|
||||
import android.sax.EndTextElementListener;
|
||||
import android.sax.RootElement;
|
||||
import android.util.Xml;
|
||||
|
||||
/**
|
||||
* Parser for the XML configuration file that defines the assets available to
|
||||
* play
|
||||
*/
|
||||
public class ConfigXMLParser {
|
||||
|
||||
private URL mFeedUrl;
|
||||
private InputStream inputStream;
|
||||
|
||||
protected InputStream getInputStream() {
|
||||
try {
|
||||
if (inputStream != null)
|
||||
return inputStream;
|
||||
else
|
||||
return mFeedUrl.openConnection().getInputStream();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigXMLParser(URL feedUrl) {
|
||||
mFeedUrl = feedUrl;
|
||||
}
|
||||
|
||||
public ConfigXMLParser(InputStream inputStream) {
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
public List<AssetDescriptor> parse() {
|
||||
final AssetDescriptor currentAssetDescriptor = new AssetDescriptor();
|
||||
RootElement root = new RootElement("widevine");
|
||||
final List<AssetDescriptor> assetDescriptors = new ArrayList<AssetDescriptor>();
|
||||
Element assetlist = root.getChild("asset-list");
|
||||
Element asset = assetlist.getChild("asset");
|
||||
asset.setEndElementListener(new EndElementListener() {
|
||||
public void end() {
|
||||
if (currentAssetDescriptor.getUri().indexOf("http") != -1
|
||||
&& (currentAssetDescriptor.getUri().indexOf(".wvm") != -1
|
||||
|| !currentAssetDescriptor.getUri().substring(currentAssetDescriptor
|
||||
.getUri().lastIndexOf("/")).contains("."))) {
|
||||
assetDescriptors.add(currentAssetDescriptor.copy());
|
||||
}
|
||||
}
|
||||
});
|
||||
asset.getChild("title").setEndTextElementListener(new EndTextElementListener() {
|
||||
public void end(String body) {
|
||||
currentAssetDescriptor.setTitle(body);
|
||||
}
|
||||
});
|
||||
asset.getChild("uri").setEndTextElementListener(new EndTextElementListener() {
|
||||
public void end(String body) {
|
||||
currentAssetDescriptor.setUri(body);
|
||||
}
|
||||
});
|
||||
asset.getChild("description").setEndTextElementListener(new EndTextElementListener() {
|
||||
public void end(String body) {
|
||||
currentAssetDescriptor.setDescription(body);
|
||||
}
|
||||
});
|
||||
asset.getChild("thumbnail").setEndTextElementListener(new EndTextElementListener() {
|
||||
public void end(String body) {
|
||||
currentAssetDescriptor.setThumbnail(body);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return assetDescriptors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DownloadActivity extends AssetActivity {
|
||||
|
||||
protected boolean setUpAssetPages() {
|
||||
pages = new ArrayList<AssetsPage>();
|
||||
|
||||
File[] assets = getDownloadedClips();
|
||||
|
||||
if (assets != null && assets.length > 0) {
|
||||
for (int i = 0; i < assets.length;) {
|
||||
AssetsPage page = new AssetsPage();
|
||||
for (int j = 0; j < AssetsPage.MAX_ITEMS && i < assets.length; j++, i++) {
|
||||
page.addPage(assets[i].getAbsolutePath(), null, null);
|
||||
}
|
||||
pages.add(page);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private File[] getDownloadedClips() {
|
||||
|
||||
File file = new File("/sdcard/Widevine");
|
||||
|
||||
FilenameFilter filter = new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
File file = new File(dir.getAbsolutePath() + File.separator + name);
|
||||
if (!file.isDirectory()
|
||||
&& !name.equals("curl")
|
||||
&& (name.contains(".wvm") || name.contains(".mp4") || !name.contains(".")))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return file.listFiles(filter);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.VideoView;
|
||||
|
||||
public class FullScreenVideoView extends VideoView {
|
||||
|
||||
private boolean fullscreen;
|
||||
private int rLeft, rRight, rTop, rBottom, regularHeight, regularWidth;
|
||||
private int fullScreenWidth, fullScreenHeight;
|
||||
|
||||
public FullScreenVideoView(Context context) {
|
||||
super(context);
|
||||
fullscreen = false;
|
||||
regularHeight = 0;
|
||||
regularWidth = 0;
|
||||
rBottom = 0;
|
||||
rRight = 0;
|
||||
rTop = 0;
|
||||
rLeft = 0;
|
||||
fullScreenWidth = 1280;
|
||||
fullScreenHeight = 800;
|
||||
}
|
||||
|
||||
public void setFullScreenDimensions(int width, int height) {
|
||||
fullScreenWidth = width;
|
||||
fullScreenHeight = height;
|
||||
}
|
||||
|
||||
public void setFullScreen(boolean fullscreen) {
|
||||
this.fullscreen = fullscreen;
|
||||
this.requestLayout();
|
||||
}
|
||||
|
||||
public boolean getFullScreen() {
|
||||
return this.fullscreen;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
if (rLeft == 0 && rRight == 0 && rTop == 0 && rBottom == 0) {
|
||||
rBottom = bottom;
|
||||
rRight = right;
|
||||
rTop = top;
|
||||
rLeft = left;
|
||||
}
|
||||
if (fullscreen) {
|
||||
super.onLayout(true, left, top, fullScreenWidth, fullScreenHeight);
|
||||
} else {
|
||||
if (rLeft == 0 && rRight == 0 && rTop == 0 && rBottom == 0) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
} else {
|
||||
super.onLayout(changed, rLeft, rTop, rRight, rBottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (regularHeight == 0 && regularWidth == 0) {
|
||||
regularHeight = heightMeasureSpec;
|
||||
regularWidth = widthMeasureSpec;
|
||||
}
|
||||
if (fullscreen) {
|
||||
this.setMeasuredDimension(fullScreenWidth, fullScreenHeight);
|
||||
} else {
|
||||
if (regularHeight == 0 && regularWidth == 0) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
} else {
|
||||
super.onMeasure(regularWidth, regularHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
111
proprietary/samplePlayer/src/com/widevine/demo/HttpParser.java
Normal file
111
proprietary/samplePlayer/src/com/widevine/demo/HttpParser.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
public class HttpParser extends Thread {
|
||||
|
||||
private ArrayList<AssetItem> assets;
|
||||
private String urlString;
|
||||
private String rootUrl;
|
||||
|
||||
public HttpParser(String urlString) {
|
||||
this.urlString = urlString;
|
||||
this.assets = new ArrayList<AssetItem>();
|
||||
this.rootUrl = this.urlString.substring(0, this.urlString.lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||
HttpGet request = new HttpGet(urlString);
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
|
||||
InputStream reader = response.getEntity().getContent();
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
int data = 0;
|
||||
do {
|
||||
data = reader.read();
|
||||
if (data == -1) {
|
||||
break;
|
||||
}
|
||||
buffer.append((char) data);
|
||||
|
||||
} while (true);
|
||||
|
||||
if (urlString.contains(".htm")) {
|
||||
parseHtml(buffer.toString());
|
||||
} else if (urlString.contains(".xml")) {
|
||||
parseXML(buffer.toString());
|
||||
}
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void parseXML(String xmlText) {
|
||||
ConfigXMLParser parser = new ConfigXMLParser(new ByteArrayInputStream(xmlText.getBytes()));
|
||||
|
||||
ArrayList<AssetDescriptor> descrs = (ArrayList<AssetDescriptor>) parser.parse();
|
||||
|
||||
for (int i = 0; i < descrs.size(); i++) {
|
||||
AssetDescriptor asset = descrs.get(i);
|
||||
String imagePath = asset.getThumbnail();
|
||||
if (!imagePath.contains("http")) {
|
||||
imagePath = rootUrl + imagePath;
|
||||
}
|
||||
assets.add(new AssetItem(asset.getUri(), asset.getThumbnail(), asset.getTitle()));
|
||||
}
|
||||
}
|
||||
|
||||
private void parseHtml(String htmlText) {
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
|
||||
while (true) {
|
||||
String assetPath = null;
|
||||
String title = null;
|
||||
String imagePath = null;
|
||||
start = htmlText.indexOf(":", start);
|
||||
if (start == -1) {
|
||||
break;
|
||||
} else {
|
||||
end = htmlText.indexOf("\"", start);
|
||||
assetPath = "http" + htmlText.substring(start, end);
|
||||
start = end + 1;
|
||||
start = htmlText.indexOf("\"", start) + 1;
|
||||
end = htmlText.indexOf("\"", start);
|
||||
imagePath = htmlText.substring(start, end);
|
||||
if (!imagePath.contains("http")) {
|
||||
imagePath = rootUrl + imagePath;
|
||||
}
|
||||
start = htmlText.indexOf("<p>", start) + "<p>".length();
|
||||
end = htmlText.indexOf("</p>", start);
|
||||
title = htmlText.substring(start, end);
|
||||
start = end + 1;
|
||||
assets.add(new AssetItem(assetPath, imagePath, title));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<AssetItem> getAssets() {
|
||||
return this.assets;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
public class ImageHandler extends Thread {
|
||||
|
||||
private boolean scale;
|
||||
private String imageUrl;
|
||||
private Bitmap clipImage = null;
|
||||
|
||||
public ImageHandler(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
this.clipImage = null;
|
||||
}
|
||||
|
||||
public void setScale(boolean scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||
HttpGet request = new HttpGet(imageUrl);
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
|
||||
this.clipImage = BitmapFactory.decodeStream(response.getEntity().getContent());
|
||||
if (scale) {
|
||||
this.clipImage = Bitmap.createScaledBitmap(this.clipImage, 150, 200, false);
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
this.clipImage = null;
|
||||
} catch (IOException e) {
|
||||
this.clipImage = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
return this.clipImage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class SettingsActivity extends Activity {
|
||||
// public static String CONTENT_PAGE = "/sdcard/Widevine/config.xml";
|
||||
public static String CONTENT_PAGE = "http://seawwws001.shibboleth.tv/android/oem.html";
|
||||
|
||||
private Context context;
|
||||
private Button updateButton;
|
||||
private EditText drmServer, portalName, deviceId, contentPage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
context = this;
|
||||
|
||||
setContentView(R.layout.settings);
|
||||
|
||||
updateButton = (Button) findViewById(R.id.update_button);
|
||||
|
||||
View.OnClickListener clickListener = new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
WidevineDrm.Settings.DRM_SERVER_URI = drmServer.getText().toString();
|
||||
WidevineDrm.Settings.DEVICE_ID = deviceId.getText().toString();
|
||||
WidevineDrm.Settings.PORTAL_NAME = portalName.getText().toString();
|
||||
SettingsActivity.CONTENT_PAGE = contentPage.getText().toString();
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage("DRM Settings Updated").setCancelable(false)
|
||||
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
};
|
||||
|
||||
updateButton.setOnClickListener(clickListener);
|
||||
|
||||
drmServer = (EditText) findViewById(R.id.drm_server);
|
||||
drmServer.setText(WidevineDrm.Settings.DRM_SERVER_URI);
|
||||
|
||||
deviceId = (EditText) findViewById(R.id.device_id);
|
||||
deviceId.setText(WidevineDrm.Settings.DEVICE_ID);
|
||||
|
||||
portalName = (EditText) findViewById(R.id.portal_id);
|
||||
portalName.setText(WidevineDrm.Settings.PORTAL_NAME);
|
||||
|
||||
contentPage = (EditText) findViewById(R.id.content_page);
|
||||
contentPage.setText(SettingsActivity.CONTENT_PAGE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
public class StreamingActivity extends AssetActivity {
|
||||
private String contentPage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
contentPage = SettingsActivity.CONTENT_PAGE;
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (!contentPage.equals(SettingsActivity.CONTENT_PAGE)) {
|
||||
contentPage = SettingsActivity.CONTENT_PAGE;
|
||||
initialize();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean setUpAssetPages() {
|
||||
pages = new ArrayList<AssetsPage>();
|
||||
|
||||
if (contentPage.contains(".htm")) {
|
||||
ArrayList<AssetItem> assets = getStreamingClipsHttp();
|
||||
|
||||
if (assets == null || assets.size() == 0)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < assets.size();) {
|
||||
AssetsPage page = new AssetsPage();
|
||||
for (int j = 0; j < AssetsPage.MAX_ITEMS && i < assets.size(); j++, i++) {
|
||||
page.addPage(assets.get(i).getAssetPath(), assets.get(i).getImagePath(), assets
|
||||
.get(i).getTitle());
|
||||
}
|
||||
pages.add(page);
|
||||
}
|
||||
} else {
|
||||
ArrayList<AssetDescriptor> assets = getStreamingClipsXml();
|
||||
|
||||
if (assets == null || assets.size() == 0)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < assets.size();) {
|
||||
AssetsPage page = new AssetsPage();
|
||||
for (int j = 0; j < AssetsPage.MAX_ITEMS && i < assets.size(); j++, i++) {
|
||||
page.addPage(assets.get(i).getUri(), assets.get(i).getThumbnail(), assets
|
||||
.get(i).getTitle());
|
||||
}
|
||||
pages.add(page);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ArrayList<AssetDescriptor> getStreamingClipsXml() {
|
||||
|
||||
try {
|
||||
File file = new File(contentPage);
|
||||
if (file.exists()) {
|
||||
ConfigXMLParser parser = new ConfigXMLParser(file.toURL());
|
||||
|
||||
ArrayList<AssetDescriptor> assets = (ArrayList<AssetDescriptor>) parser.parse();
|
||||
return assets;
|
||||
} else {
|
||||
return new ArrayList<AssetDescriptor>();
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
return new ArrayList<AssetDescriptor>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ArrayList<AssetItem> getStreamingClipsHttp() {
|
||||
HttpParser parser = new HttpParser(contentPage);
|
||||
parser.start();
|
||||
try {
|
||||
parser.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
return parser.getAssets();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class SwipeLinearLayout extends LinearLayout {
|
||||
private View.OnClickListener prev;
|
||||
private View.OnClickListener next;
|
||||
|
||||
float startX, startY, endX, endY;
|
||||
|
||||
public SwipeLinearLayout(Context c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public void setNext(View.OnClickListener next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public void setPrev(View.OnClickListener prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
if (e.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
startX = e.getX();
|
||||
startY = e.getY();
|
||||
return true;
|
||||
} else if (e.getAction() == MotionEvent.ACTION_UP) {
|
||||
endX = e.getX();
|
||||
endY = e.getY();
|
||||
|
||||
if (Math.abs(startY - endY) < 75) {
|
||||
if ((startX - endX) > 200.0) {
|
||||
// go forward
|
||||
if (next != null) {
|
||||
next.onClick(null);
|
||||
}
|
||||
} else if ((startX - endX) < -200.0) {
|
||||
// go back
|
||||
if (prev != null) {
|
||||
prev.onClick(null);
|
||||
}
|
||||
}
|
||||
startX = startY = endX = endY = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.MediaController;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Button;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.content.Context;
|
||||
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaPlayer.OnErrorListener;
|
||||
import android.media.MediaPlayer.OnCompletionListener;
|
||||
|
||||
public class VideoPlayerView extends Activity {
|
||||
private final static String EXIT_FULLSCREEN = "Exit Full Screen";
|
||||
private final static String FULLSCREEN = "Enter Full Screen";
|
||||
private final static String PLAY = "Play";
|
||||
private final static int REFRESH = 1;
|
||||
|
||||
private WidevineDrm drm;
|
||||
private FullScreenVideoView videoView;
|
||||
private String assetUri;
|
||||
private TextView logs;
|
||||
private ScrollView scrollView;
|
||||
private Context context;
|
||||
private ClipImageView bgImage;
|
||||
private Button playButton;
|
||||
private Button fullScreen;
|
||||
private Handler hRefresh;
|
||||
private View contentView;
|
||||
private LinearLayout main;
|
||||
private LinearLayout sidePanel;
|
||||
private boolean enteringFullScreen;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
context = this;
|
||||
contentView = createView();
|
||||
setContentView(contentView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
if (videoView != null) {
|
||||
if (videoView.isPlaying()) {
|
||||
stopPlayback();
|
||||
}
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
private View createView() {
|
||||
enteringFullScreen = false;
|
||||
assetUri = this.getIntent().getStringExtra("com.widevine.demo.Path");
|
||||
|
||||
drm = new WidevineDrm(this);
|
||||
drm.logBuffer.append("Asset Uri: " + assetUri + "\n");
|
||||
drm.logBuffer.append("Drm Server: " + WidevineDrm.Settings.DRM_SERVER_URI + "\n");
|
||||
drm.logBuffer.append("Device Id: " + WidevineDrm.Settings.DEVICE_ID + "\n");
|
||||
drm.logBuffer.append("Portal Name: " + WidevineDrm.Settings.PORTAL_NAME + "\n");
|
||||
|
||||
// Set log update listener
|
||||
WidevineDrm.WidevineDrmLogEventListener drmLogListener =
|
||||
new WidevineDrm.WidevineDrmLogEventListener() {
|
||||
|
||||
public void logUpdated() {
|
||||
updateLogs();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
videoView = new FullScreenVideoView(this);
|
||||
|
||||
logs = new TextView(this);
|
||||
drm.setLogListener(drmLogListener);
|
||||
|
||||
scrollView = new ScrollView(this);
|
||||
scrollView.addView(logs);
|
||||
|
||||
// Set message handler for log events
|
||||
hRefresh = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case REFRESH:
|
||||
/* Refresh UI */
|
||||
logs.setText(drm.logBuffer.toString());
|
||||
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateLogs();
|
||||
|
||||
sidePanel = new LinearLayout(this);
|
||||
sidePanel.setOrientation(LinearLayout.VERTICAL);
|
||||
sidePanel.addView(scrollView, new LinearLayout.LayoutParams(300, 450));
|
||||
|
||||
LinearLayout.LayoutParams paramsSidePanel = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
paramsSidePanel.gravity = Gravity.CENTER;
|
||||
sidePanel.addView(createButtons(), paramsSidePanel);
|
||||
|
||||
FrameLayout playerFrame = new FrameLayout(this);
|
||||
playerFrame.addView(videoView, new FrameLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.MATCH_PARENT));
|
||||
|
||||
bgImage = new ClipImageView(this);
|
||||
bgImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.play_shield));
|
||||
|
||||
bgImage.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
startPlayback();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
fullScreen = new Button(this);
|
||||
fullScreen.setText(FULLSCREEN);
|
||||
|
||||
fullScreen.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
int currentPosition = videoView.getCurrentPosition();
|
||||
videoView.setVisibility(View.INVISIBLE);
|
||||
if (fullScreen.getText().equals(FULLSCREEN)) {
|
||||
|
||||
videoView.setFullScreen(true);
|
||||
fullScreen.setText(EXIT_FULLSCREEN);
|
||||
enteringFullScreen = true;
|
||||
} else {
|
||||
videoView.setFullScreen(false);
|
||||
fullScreen.setText(FULLSCREEN);
|
||||
}
|
||||
videoView.setVisibility(View.VISIBLE);
|
||||
|
||||
stopPlayback();
|
||||
startPlayback();
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
videoView.seekTo(currentPosition);
|
||||
}
|
||||
});
|
||||
playerFrame.addView(fullScreen, new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT));
|
||||
fullScreen.setVisibility(View.INVISIBLE);
|
||||
playerFrame.addView(bgImage, new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
main = new LinearLayout(this);
|
||||
main.addView(playerFrame, new LinearLayout.LayoutParams(900,
|
||||
LinearLayout.LayoutParams.FILL_PARENT, 1));
|
||||
main.addView(sidePanel, new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.FILL_PARENT, 3));
|
||||
|
||||
return main;
|
||||
}
|
||||
|
||||
private void startPlayback() {
|
||||
playButton.setText(R.string.stop);
|
||||
|
||||
bgImage.setVisibility(View.GONE);
|
||||
|
||||
videoView.setVideoPath(assetUri);
|
||||
videoView.setMediaController(new MediaController(context));
|
||||
|
||||
videoView.setOnErrorListener(new OnErrorListener() {
|
||||
public boolean onError(MediaPlayer mp, int what, int extra) {
|
||||
String message = "Unknown error";
|
||||
switch (what) {
|
||||
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
|
||||
message = "Unable to play media";
|
||||
break;
|
||||
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
|
||||
message = "Server failed";
|
||||
break;
|
||||
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
|
||||
message = "Invalid media";
|
||||
break;
|
||||
}
|
||||
drm.logBuffer.append(message + "\n");
|
||||
updateLogs();
|
||||
bgImage.setVisibility(View.VISIBLE);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
videoView.setOnCompletionListener(new OnCompletionListener() {
|
||||
public void onCompletion(MediaPlayer mp) {
|
||||
stopPlayback();
|
||||
}
|
||||
});
|
||||
videoView.requestFocus();
|
||||
|
||||
videoView.start();
|
||||
|
||||
if (videoView.getFullScreen()) {
|
||||
sidePanel.setVisibility(View.GONE);
|
||||
} else {
|
||||
sidePanel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
fullScreen.setVisibility(View.VISIBLE);
|
||||
videoView.setFullScreenDimensions(contentView.getRight() - contentView.getLeft(),
|
||||
contentView.getBottom() - contentView.getTop());
|
||||
}
|
||||
|
||||
private void stopPlayback() {
|
||||
playButton.setText(R.string.play);
|
||||
videoView.stopPlayback();
|
||||
fullScreen.setVisibility(View.INVISIBLE);
|
||||
bgImage.setVisibility(View.VISIBLE);
|
||||
|
||||
if (videoView.getFullScreen() && !enteringFullScreen) {
|
||||
videoView.setVisibility(View.INVISIBLE);
|
||||
videoView.setFullScreen(false);
|
||||
videoView.setVisibility(View.VISIBLE);
|
||||
sidePanel.setVisibility(View.VISIBLE);
|
||||
fullScreen.setText(FULLSCREEN);
|
||||
}
|
||||
enteringFullScreen = false;
|
||||
|
||||
}
|
||||
|
||||
private View createButtons() {
|
||||
playButton = new Button(this);
|
||||
playButton.setText(R.string.play);
|
||||
|
||||
playButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
Button b = (Button) v;
|
||||
if (b.getText().equals(PLAY)) {
|
||||
startPlayback();
|
||||
} else {
|
||||
stopPlayback();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Button rightsButton = new Button(this);
|
||||
rightsButton.setText(R.string.acquire_rights);
|
||||
|
||||
rightsButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
drm.acquireRights(assetUri);
|
||||
updateLogs();
|
||||
}
|
||||
});
|
||||
|
||||
Button removeButton = new Button(this);
|
||||
removeButton.setText(R.string.remove_rights);
|
||||
|
||||
removeButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
drm.removeRights(assetUri);
|
||||
updateLogs();
|
||||
}
|
||||
});
|
||||
|
||||
Button checkButton = new Button(this);
|
||||
checkButton.setText(R.string.show_rights);
|
||||
|
||||
checkButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
drm.showRights(assetUri);
|
||||
updateLogs();
|
||||
}
|
||||
});
|
||||
|
||||
Button checkConstraints = new Button(this);
|
||||
checkConstraints.setText(R.string.constraints);
|
||||
|
||||
checkConstraints.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
drm.getConstraints(assetUri);
|
||||
updateLogs();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.FILL_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
|
||||
params.setMargins(0, 0, 0, 5);
|
||||
LinearLayout buttonsLeft = new LinearLayout(this);
|
||||
|
||||
buttonsLeft.setOrientation(LinearLayout.VERTICAL);
|
||||
buttonsLeft.addView(playButton, params);
|
||||
buttonsLeft.addView(rightsButton, params);
|
||||
buttonsLeft.addView(checkConstraints, params);
|
||||
|
||||
LinearLayout buttonsRight = new LinearLayout(this);
|
||||
buttonsRight.setOrientation(LinearLayout.VERTICAL);
|
||||
buttonsRight.addView(checkButton, params);
|
||||
buttonsRight.addView(removeButton, params);
|
||||
|
||||
LinearLayout.LayoutParams paramsSides = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.FILL_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT, 1);
|
||||
paramsSides.gravity = Gravity.BOTTOM;
|
||||
|
||||
LinearLayout buttons = new LinearLayout(this);
|
||||
buttons.addView(buttonsLeft, paramsSides);
|
||||
buttons.addView(buttonsRight, paramsSides);
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
private void updateLogs() {
|
||||
hRefresh.sendEmptyMessage(REFRESH);
|
||||
}
|
||||
}
|
||||
252
proprietary/samplePlayer/src/com/widevine/demo/WidevineDrm.java
Normal file
252
proprietary/samplePlayer/src/com/widevine/demo/WidevineDrm.java
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import java.util.EventListener;
|
||||
//import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
|
||||
import android.drm.DrmErrorEvent;
|
||||
import android.drm.DrmEvent;
|
||||
import android.drm.DrmInfoEvent;
|
||||
import android.drm.DrmInfoRequest;
|
||||
import android.drm.DrmManagerClient;
|
||||
import android.drm.DrmStore;
|
||||
|
||||
public class WidevineDrm {
|
||||
|
||||
interface WidevineDrmLogEventListener extends EventListener {
|
||||
public void logUpdated();
|
||||
}
|
||||
|
||||
private WidevineDrmLogEventListener logEventListener;
|
||||
|
||||
public StringBuffer logBuffer = new StringBuffer();
|
||||
|
||||
/**
|
||||
* Drm Manager Configuration Methods
|
||||
*/
|
||||
|
||||
public static class Settings {
|
||||
public static String WIDEVINE_MIME_TYPE = "video/wvm";
|
||||
public static String DRM_SERVER_URI = "https://wstfcps005.shibboleth.tv/widevine/cypherpc/cgi-bin/GetEMMs.cgi";
|
||||
public static String DEVICE_ID = "device12345"; // use a unique device ID
|
||||
public static String PORTAL_NAME = "OEM";
|
||||
|
||||
// test with a sizeable block of user data...
|
||||
public static String USER_DATA = "01234567890123456789012345678901234567890123456789"
|
||||
+ "01234567890123456789012345678901234567890123456789"
|
||||
+ "01234567890123456789012345678901234567890123456789"
|
||||
+ "01234567890123456789012345678901234567890123456789"
|
||||
+ "01234567890123456789012345678901234567890123456789"
|
||||
+ "01234567890123456789012345678901234567890123456789";
|
||||
};
|
||||
|
||||
private DrmManagerClient mDrmManager;
|
||||
|
||||
// private Context mContext;
|
||||
|
||||
public WidevineDrm(Context context) {
|
||||
|
||||
// mContext = context;
|
||||
mDrmManager = new DrmManagerClient(context);
|
||||
|
||||
mDrmManager.setOnInfoListener(new DrmManagerClient.OnInfoListener() {
|
||||
// @Override
|
||||
public void onInfo(DrmManagerClient client, DrmInfoEvent event) {
|
||||
if (event.getType() == DrmInfoEvent.TYPE_RIGHTS_INSTALLED) {
|
||||
logMessage("Rights installed\n");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mDrmManager.setOnEventListener(new DrmManagerClient.OnEventListener() {
|
||||
|
||||
public void onEvent(DrmManagerClient client, DrmEvent event) {
|
||||
switch (event.getType()) {
|
||||
case DrmEvent.TYPE_DRM_INFO_PROCESSED:
|
||||
logMessage("Info Processed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mDrmManager.setOnErrorListener(new DrmManagerClient.OnErrorListener() {
|
||||
public void onError(DrmManagerClient client, DrmErrorEvent event) {
|
||||
switch (event.getType()) {
|
||||
case DrmErrorEvent.TYPE_ALL_RIGHTS_REMOVED:
|
||||
logMessage("Remove All Rights failed\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_DRM_INFO_PROCESSED:
|
||||
logMessage("Info Processed failed\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_NO_INTERNET_CONNECTION:
|
||||
logMessage("No Internet Connection\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_NOT_SUPPORTED:
|
||||
logMessage("Not Supported\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_OUT_OF_MEMORY:
|
||||
logMessage("Out of Memory\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_PROCESS_DRM_INFO_FAILED:
|
||||
logMessage("Process DRM Info failed\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED:
|
||||
logMessage("Remove all rights\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_RIGHTS_NOT_INSTALLED:
|
||||
logMessage("Rights not installed\n");
|
||||
break;
|
||||
case DrmErrorEvent.TYPE_RIGHTS_RENEWAL_NOT_ALLOWED:
|
||||
logMessage("Rights renewal not allowed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public DrmInfoRequest getDrmInfoRequest(String assetUri) {
|
||||
DrmInfoRequest rightsAcquisitionInfo;
|
||||
rightsAcquisitionInfo = new DrmInfoRequest(DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO,
|
||||
Settings.WIDEVINE_MIME_TYPE);
|
||||
|
||||
rightsAcquisitionInfo.put("WVDRMServerKey", Settings.DRM_SERVER_URI);
|
||||
rightsAcquisitionInfo.put("WVAssetURIKey", assetUri);
|
||||
rightsAcquisitionInfo.put("WVDeviceIDKey", Settings.DEVICE_ID);
|
||||
rightsAcquisitionInfo.put("WVPortalKey", Settings.PORTAL_NAME);
|
||||
rightsAcquisitionInfo.put("WVCAUserDataKey", Settings.USER_DATA);
|
||||
return rightsAcquisitionInfo;
|
||||
}
|
||||
|
||||
public int acquireRights(String assetUri) {
|
||||
|
||||
int rights = mDrmManager.acquireRights(getDrmInfoRequest(assetUri));
|
||||
logMessage("acquireRights = " + rights + "\n");
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
public int checkRightsStatus(String assetUri) {
|
||||
|
||||
// Need to use acquireDrmInfo prior to calling checkRightsStatus
|
||||
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
|
||||
int status = mDrmManager.checkRightsStatus(assetUri);
|
||||
logMessage("checkRightsStatus = " + status + "\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public void getConstraints(String assetUri) {
|
||||
|
||||
// Need to use acquireDrmInfo prior to calling checkRightsStatus
|
||||
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
|
||||
ContentValues values = mDrmManager.getConstraints(assetUri, DrmStore.Action.PLAY);
|
||||
logContentValues(values, "No Contraints");
|
||||
}
|
||||
|
||||
public void showRights(String assetUri) {
|
||||
logMessage("showRights\n");
|
||||
|
||||
// Need to use acquireDrmInfo prior to calling getConstraints
|
||||
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
|
||||
|
||||
ContentValues values = mDrmManager.getConstraints(assetUri, DrmStore.Action.PLAY);
|
||||
logContentValues(values, "No Rights");
|
||||
|
||||
}
|
||||
|
||||
private void logContentValues(ContentValues values, String defaultMessage) {
|
||||
if (values != null) {
|
||||
|
||||
Set<String> keys = values.keySet();
|
||||
for (String key : keys) {
|
||||
if (key.toLowerCase().contains("time")) {
|
||||
logMessage(key + " = " + SecondsToDHMS(values.getAsLong(key)) + "\n");
|
||||
} else if (key.toLowerCase().contains("licensetype")) {
|
||||
logMessage(key + " = " + licenseType(values.getAsInteger(key)) + "\n");
|
||||
} else if (key.toLowerCase().contains("licensedresolution")) {
|
||||
logMessage(key + " = " + licenseResolution(values.getAsInteger(key)) + "\n");
|
||||
} else {
|
||||
logMessage(key + " = " + values.get(key) + "\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logMessage(defaultMessage + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static final long seconds_per_minute = 60;
|
||||
private static final long seconds_per_hour = 60 * seconds_per_minute;
|
||||
private static final long seconds_per_day = 24 * seconds_per_hour;
|
||||
|
||||
private String SecondsToDHMS(long seconds) {
|
||||
int days = (int) (seconds / seconds_per_day);
|
||||
seconds -= days * seconds_per_day;
|
||||
int hours = (int) (seconds / seconds_per_hour);
|
||||
seconds -= hours * seconds_per_hour;
|
||||
int minutes = (int) (seconds / seconds_per_minute);
|
||||
seconds -= minutes * seconds_per_minute;
|
||||
return Integer.toString(days) + "d " + Integer.toString(hours) + "h "
|
||||
+ Integer.toString(minutes) + "m " + Long.toString(seconds)
|
||||
+ "s";
|
||||
}
|
||||
|
||||
private String licenseType(int code) {
|
||||
switch (code) {
|
||||
case 1:
|
||||
return "Streaming";
|
||||
case 2:
|
||||
return "Offline";
|
||||
case 3:
|
||||
return "Both";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
private String licenseResolution(int code) {
|
||||
switch (code) {
|
||||
case 1:
|
||||
return "SD only";
|
||||
case 2:
|
||||
return "HD or SD content";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public int removeRights(String assetUri) {
|
||||
|
||||
// Need to use acquireDrmInfo prior to calling removeRights
|
||||
mDrmManager.acquireDrmInfo(getDrmInfoRequest(assetUri));
|
||||
int removeStatus = mDrmManager.removeRights(assetUri);
|
||||
logMessage("removeRights = " + removeStatus + "\n");
|
||||
|
||||
return removeStatus;
|
||||
}
|
||||
|
||||
public int removeAllRights() {
|
||||
int removeAllStatus = mDrmManager.removeAllRights();
|
||||
logMessage("removeAllRights = " + removeAllStatus + "\n");
|
||||
return removeAllStatus;
|
||||
}
|
||||
|
||||
public void setLogListener(WidevineDrmLogEventListener logEventListener) {
|
||||
this.logEventListener = logEventListener;
|
||||
}
|
||||
|
||||
private void logMessage(String message) {
|
||||
logBuffer.append(message);
|
||||
|
||||
if (logEventListener != null) {
|
||||
logEventListener.logUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* (c)Copyright 2011 Widevine Technologies, Inc
|
||||
*/
|
||||
|
||||
package com.widevine.demo;
|
||||
|
||||
import android.app.TabActivity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TabHost;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
public class WidevineSamplePlayer extends TabActivity {
|
||||
|
||||
public static final String PREFS_NAME = "DrmPrefs";
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
|
||||
WidevineDrm.Settings.DRM_SERVER_URI = settings.getString("drmServer",
|
||||
WidevineDrm.Settings.DRM_SERVER_URI);
|
||||
WidevineDrm.Settings.DEVICE_ID = settings.getString("deviceId",
|
||||
WidevineDrm.Settings.DEVICE_ID);
|
||||
WidevineDrm.Settings.PORTAL_NAME = settings.getString("portalId",
|
||||
WidevineDrm.Settings.PORTAL_NAME);
|
||||
SettingsActivity.CONTENT_PAGE = settings.getString("contentPage",
|
||||
SettingsActivity.CONTENT_PAGE);
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
TabHost tab = getTabHost();
|
||||
|
||||
// Setup Streaming tab
|
||||
TabHost.TabSpec streamingTab = tab.newTabSpec("Streaming");
|
||||
|
||||
streamingTab.setIndicator("Streaming");
|
||||
|
||||
Intent streamingIntent = new Intent(this, StreamingActivity.class);
|
||||
streamingTab.setContent(streamingIntent);
|
||||
|
||||
tab.addTab(streamingTab);
|
||||
|
||||
// Setup Down load tab
|
||||
TabHost.TabSpec downloadTab = tab.newTabSpec("Downloads");
|
||||
|
||||
downloadTab.setIndicator("Downloads");
|
||||
|
||||
Intent downloadIntent = new Intent(this, DownloadActivity.class);
|
||||
downloadTab.setContent(downloadIntent);
|
||||
|
||||
tab.addTab(downloadTab);
|
||||
|
||||
// Setup Settings tab
|
||||
TabHost.TabSpec settingsTab = tab.newTabSpec("Settings");
|
||||
|
||||
settingsTab.setIndicator("Settings");
|
||||
|
||||
Intent settingsIntent = new Intent(this, SettingsActivity.class);
|
||||
settingsTab.setContent(settingsIntent);
|
||||
|
||||
tab.addTab(settingsTab);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
|
||||
// We need an Editor object to make preference changes.
|
||||
// All objects are from android.context.Context
|
||||
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
|
||||
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString("drmServer", WidevineDrm.Settings.DRM_SERVER_URI);
|
||||
editor.putString("deviceId", WidevineDrm.Settings.DEVICE_ID);
|
||||
editor.putString("portalId", WidevineDrm.Settings.PORTAL_NAME);
|
||||
editor.putString("contentPage", SettingsActivity.CONTENT_PAGE);
|
||||
// Commit the edits!
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user