Commit 6bc29a80 by 黄晋宇

Initial commit

parents
*.iml
.gradle
/local.properties
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild
apply plugin: 'com.android.library'
android {
compileSdkVersion externalCompileSdkVersion
defaultConfig {
minSdkVersion externalMinSdkVersion
targetSdkVersion externalTargetSdkVersion
consumerProguardFiles 'lib-proguard-rules.pro'
}
lintOptions {
warning 'InvalidPackage'
}
}
dependencies {
api project(':PolyvSVideoBase')
implementation externalGSON
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Users\Administrator\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#glide配置
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.polyv.demo.crop">
<application>
<activity
android:name=".PolyvMediaActivity"
android:screenOrientation="portrait"
android:theme="@style/polyvVideoUIStytle"
tools:replace="android:theme"></activity>
<activity
android:name=".PolyvVideoCropActivity"
android:screenOrientation="portrait"
android:theme="@style/polyvVideoUIStytle"
tools:replace="android:theme"></activity>
<activity
android:name=".PolyvImageCropActivity"
android:screenOrientation="portrait"
android:theme="@style/polyvVideoUIStytle"
tools:replace="android:theme"></activity>
</application>
</manifest>
package com.polyv.demo.crop.media;
import com.polyv.shortvideo.sdk.common.buffer.PolyvAllocator;
import com.polyv.shortvideo.sdk.common.buffer.PolyvRecycler;
public class PolyvBitmapAllocator implements PolyvAllocator<PolyvShareableBitmap> {
private final int _Width;
private final int _Height;
public PolyvBitmapAllocator(int w, int h) {
_Width = w;
_Height = h;
}
@Override
public PolyvShareableBitmap allocate(PolyvRecycler<PolyvShareableBitmap> recycler, PolyvShareableBitmap reused) {
if (reused != null) {
reused.reset();
return reused;
}
return new PolyvShareableBitmap(recycler, _Width, _Height);
}
@Override
public void recycle(PolyvShareableBitmap object) {
}
@Override
public void release(PolyvShareableBitmap object) {
object.getData().recycle();
}
}
package com.polyv.demo.crop.media;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.media.MediaMetadataRetriever;
import android.os.AsyncTask;
import android.util.SparseArray;
import com.polyv.shortvideo.sdk.common.buffer.PolyvSynchronizedPool;
import com.polyv.shortvideo.sdk.common.logger.PolyvLogger;
import java.lang.ref.WeakReference;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class PolyvFrameExtractor10 {
private static final String TAG = "FrameExtractor";
private final ExecutorService mExecutor;
private final MediaMetadataRetriever mRetriever = new MediaMetadataRetriever();
private final PolyvSynchronizedPool<PolyvShareableBitmap> mBitmapPool;
private final Canvas mCanvas = new Canvas();
private final Rect mRect = new Rect();
private SparseArray mMetaDataCache = new SparseArray();
private String mVideoPath;
public PolyvFrameExtractor10() {
mExecutor = Executors.newSingleThreadExecutor();
int width = 128;
int height = 128;
mBitmapPool = new PolyvSynchronizedPool<>(new PolyvBitmapAllocator(width, height));
mRect.set(0, 0, width, height);
}
public AsyncTask<Void, Void, PolyvShareableBitmap> newTask(Callback callback, long timestamp_nano) {
return new Task(callback, timestamp_nano).executeOnExecutor(mExecutor);
}
public boolean setDataSource(String source) {
try {
mVideoPath = source;
mRetriever.setDataSource(source);
} catch (Exception e) {
return false;
}
return true;
}
public long getVideoDuration() {
Object result;
if ((result = mMetaDataCache.get(MediaMetadataRetriever.METADATA_KEY_DURATION)) != null) {
return (Long) result;
} else if (mVideoPath != null) {
String durationStr = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (durationStr != null && !"".equals(durationStr)) {
Long duration = Long.parseLong(durationStr);
mMetaDataCache.put(MediaMetadataRetriever.METADATA_KEY_DURATION, duration);
return duration;
} else {
PolyvLogger.getDefaultLogger().e("Retrieve video duration failed");
return 0;
}
} else {
PolyvLogger.getDefaultLogger().e("Has no video source,so duration is 0");
return 0;
}
}
public void release() {
mExecutor.shutdownNow();
while (true) {
try {
if (mExecutor.awaitTermination(1, TimeUnit.SECONDS)) {
break;
}
} catch (InterruptedException e) {
}
}
mRetriever.release();
mBitmapPool.release();
}
public interface Callback {
void onFrameExtracted(PolyvShareableBitmap bitmap, long timestamp);
}
private class Task extends AsyncTask<Void, Void, PolyvShareableBitmap> {
private final long _TimestampNano;
private WeakReference<Callback> mCallback;
public Task(Callback callback, long timestamp_nano) {
mCallback = new WeakReference<>(callback);
_TimestampNano = timestamp_nano;
}
@Override
protected PolyvShareableBitmap doInBackground(Void... params) {
if (isCancelled()) {
return null;
}
long micro = TimeUnit.NANOSECONDS.toMicros(_TimestampNano);
Bitmap bmp = mRetriever.getFrameAtTime(micro);
if (bmp == null) {
return null;
}
if (isCancelled()) {
return null;
}
PolyvShareableBitmap bitmap = mBitmapPool.allocate();
mCanvas.setBitmap(bitmap.getData());
Rect srcRect = new Rect();
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
if (bmpWidth >= bmpHeight) {
srcRect.left = (bmpWidth - bmpHeight) / 2;
srcRect.right = (bmpWidth - bmpHeight) / 2 + bmpHeight;
srcRect.top = 0;
srcRect.bottom = bmpHeight;
} else {
srcRect.left = 0;
srcRect.right = bmpWidth;
srcRect.top = (bmpHeight - bmpWidth) / 2;
srcRect.bottom = (bmpHeight - bmpWidth) / 2 + bmpWidth;
}
mCanvas.drawBitmap(bmp, srcRect, mRect, null);
bmp.recycle();
return bitmap;
}
@Override
protected void onCancelled(PolyvShareableBitmap bitmap) {
if (bitmap != null) {
bitmap.release();
}
}
@Override
protected void onPostExecute(PolyvShareableBitmap bitmap) {
Callback callback = mCallback.get();
if (callback != null) {
callback.onFrameExtracted(bitmap, _TimestampNano);
}
}
}
}
package com.polyv.demo.crop.media;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.polyv.demo.crop.R;
import java.util.List;
public class PolyvGalleryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
implements View.OnClickListener {
private static final int TYPE_ITEM_RECORD = 0;
private static final int TYPE_ITEM_MEDIA = 1;
private List<PolyvMediaInfo> medias;
private boolean needRecord = false;
private int draftCount;
private PolyvThumbnailGenerator thumbnailGenerator;
private OnItemClickListener onItemClickListener;
private int activeAdapterPosition = 0;
public PolyvGalleryAdapter(PolyvThumbnailGenerator thumbnailGenerator, boolean needRecord) {
this.thumbnailGenerator = thumbnailGenerator;
this.needRecord = needRecord;
}
public void setData(List<PolyvMediaInfo> list) {
medias = list;
notifyDataSetChanged();
}
public void setDraftCount(int draftCount) {
this.draftCount = draftCount;
}
// public void addDraftItem(){
// hasDraft = true;
// }
//
// public boolean isHasDraft() {
// return hasDraft;
// }
//
// public void removeDraftItem(){
// hasDraft = false;
// }
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder;
holder = new PolyvGalleryItemViewHolder(
LayoutInflater.from(parent.getContext()).inflate(
R.layout.polyv_svideo_item_qupai_gallery_media, parent, false), thumbnailGenerator);
holder.itemView.setOnClickListener(this);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
boolean actived = activeAdapterPosition == position;
((PolyvGalleryItemViewHolder) holder).onBind(getItem(position), actived);
}
public PolyvMediaInfo getItem(int position) {
// if(medias.size() > 0){
if (position < 0 || position >= medias.size()) {
return null;
}
if (getItemViewType(position) == TYPE_ITEM_RECORD) {
return null;
} else if (getItemViewType(position) == TYPE_ITEM_MEDIA) {
if (needRecord) {
return medias.get(position - 1);
} else {
return medias.get(position);
}
}
return medias.get(position);
}
@Override
public int getItemViewType(int position) {
if (needRecord && position == 0) {
return TYPE_ITEM_RECORD;
}
return TYPE_ITEM_MEDIA;
}
public int setActiveDataItem(PolyvMediaInfo info) {
return setActiveDataItem(info == null ? -1 : info.id);
}
public int setActiveDataItem(int id) {
int dataPosition = findDataPosition(id);
setActiveAdapterItem(dataPosition);
return dataPosition;
}
private void setActiveAdapterItem(int adapterPos) {
int oldAdapterPos = activeAdapterPosition;
if (oldAdapterPos == adapterPos) {
return;
}
activeAdapterPosition = adapterPos;
notifyItemChanged(adapterPos);
notifyItemChanged(oldAdapterPos);
}
public int getActiveAdapterPosition() {
return activeAdapterPosition;
}
public int findDataPosition(int id) {
for (int i = 0; i < medias.size(); i++) {
PolyvMediaInfo info = medias.get(i);
if (info.id == id) {
return i;
}
}
return -1;
}
@Override
public int getItemCount() {
if (needRecord) {
return medias.size() + 1;
}
return medias.size();
}
@Override
public void onClick(View v) {
RecyclerView.ViewHolder holder = (RecyclerView.ViewHolder) v.getTag();
int adapterPos = holder.getAdapterPosition();
if (onItemClickListener != null) {
Log.d("active", "onItemClick");
if (!onItemClickListener.onItemClick(this, adapterPos)) {
Log.d("active", "onItemClick1");
return;
}
}
setActiveAdapterItem(adapterPos);
}
public interface OnItemClickListener {
boolean onItemClick(PolyvGalleryAdapter adapter, int adapterPosition);
}
}
package com.polyv.demo.crop.media;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.polyv.demo.crop.R;
import java.util.List;
public class PolyvGalleryDirAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
implements View.OnClickListener {
private PolyvThumbnailGenerator thumbnailGenerator;
private List<PolyvMediaDir> mediaDirs;
private int allFileCount;
private OnItemClickListener onItemClickListener;
public PolyvGalleryDirAdapter(PolyvThumbnailGenerator thumbnailGenerator) {
this.thumbnailGenerator = thumbnailGenerator;
}
public void setData(List<PolyvMediaDir> mediaDirs) {
this.mediaDirs = mediaDirs;
notifyDataSetChanged();
}
public void setAllFileCount(int allFileCount) {
this.allFileCount = allFileCount;
notifyItemChanged(0);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder = new PolyvGalleryDirViewHolder(
LayoutInflater.from(parent.getContext()).inflate(
R.layout.polyv_svideo_item_qupai_gallery_dir, null, false), thumbnailGenerator);
holder.itemView.setOnClickListener(this);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((PolyvGalleryDirViewHolder) holder).setData(getItem(position));
if (position == 0) {