Commit 62c5d8753581a9772a3114aa2325eaa6b7419588
1 parent
3b21c068
更新短视频SDK,添加获取短视频列表接口,更新短视频文档
Showing
23 changed files
with
1398 additions
and
7 deletions
app/libs/libcnlivelive.jar
No preview for this file type
app/libs/libcnliveshortvideo.jar
No preview for this file type
app/src/main/AndroidManifest.xml
| @@ -20,14 +20,14 @@ | @@ -20,14 +20,14 @@ | ||
| 20 | <uses-permission android:name="android.permission.VIBRATE" /> | 20 | <uses-permission android:name="android.permission.VIBRATE" /> |
| 21 | 21 | ||
| 22 | <application | 22 | <application |
| 23 | - android:name="com.cnlive.demo.shortvideo.application.CNShrotVideoApplication" | 23 | + android:name=".application.CNShrotVideoApplication" |
| 24 | android:allowBackup="true" | 24 | android:allowBackup="true" |
| 25 | android:icon="@mipmap/ic_launcher" | 25 | android:icon="@mipmap/ic_launcher" |
| 26 | android:label="@string/app_name" | 26 | android:label="@string/app_name" |
| 27 | android:roundIcon="@mipmap/ic_launcher_round" | 27 | android:roundIcon="@mipmap/ic_launcher_round" |
| 28 | android:supportsRtl="true" | 28 | android:supportsRtl="true" |
| 29 | android:theme="@style/AppTheme"> | 29 | android:theme="@style/AppTheme"> |
| 30 | - <activity android:name="com.cnlive.demo.shortvideo.ui.activity.MainActivity"> | 30 | + <activity android:name=".ui.activity.MainActivity"> |
| 31 | <intent-filter> | 31 | <intent-filter> |
| 32 | <action android:name="android.intent.action.MAIN" /> | 32 | <action android:name="android.intent.action.MAIN" /> |
| 33 | 33 | ||
| @@ -35,18 +35,20 @@ | @@ -35,18 +35,20 @@ | ||
| 35 | </intent-filter> | 35 | </intent-filter> |
| 36 | </activity> | 36 | </activity> |
| 37 | <activity | 37 | <activity |
| 38 | - android:name="com.cnlive.demo.shortvideo.ui.activity.RecordActivity" | 38 | + android:name=".ui.activity.RecordActivity" |
| 39 | android:configChanges="orientation|keyboardHidden|screenSize" | 39 | android:configChanges="orientation|keyboardHidden|screenSize" |
| 40 | android:launchMode="singleTop" | 40 | android:launchMode="singleTop" |
| 41 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> | 41 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
| 42 | <activity | 42 | <activity |
| 43 | - android:name="com.cnlive.demo.shortvideo.ui.activity.EditActivity" | 43 | + android:name=".ui.activity.EditActivity" |
| 44 | android:configChanges="orientation|keyboardHidden|screenSize" | 44 | android:configChanges="orientation|keyboardHidden|screenSize" |
| 45 | android:launchMode="singleTop" | 45 | android:launchMode="singleTop" |
| 46 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> | 46 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
| 47 | <activity | 47 | <activity |
| 48 | - android:name="com.cnlive.demo.shortvideo.ui.activity.FileImportActivity" | 48 | + android:name=".ui.activity.FileImportActivity" |
| 49 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> | 49 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
| 50 | + <activity android:name=".ui.activity.ListVideoActivity"></activity> | ||
| 51 | + <activity android:name=".ui.activity.ShortVideoPlayActivity"/> | ||
| 50 | </application> | 52 | </application> |
| 51 | 53 | ||
| 52 | </manifest> | 54 | </manifest> |
| 53 | \ No newline at end of file | 55 | \ No newline at end of file |
app/src/main/java/com/cnlive/demo/shortvideo/file/FileUtils.java
| @@ -5,6 +5,7 @@ import android.content.Context; | @@ -5,6 +5,7 @@ import android.content.Context; | ||
| 5 | import android.content.Intent; | 5 | import android.content.Intent; |
| 6 | import android.database.Cursor; | 6 | import android.database.Cursor; |
| 7 | import android.database.DatabaseUtils; | 7 | import android.database.DatabaseUtils; |
| 8 | +import android.graphics.Bitmap; | ||
| 8 | import android.net.Uri; | 9 | import android.net.Uri; |
| 9 | import android.os.Build; | 10 | import android.os.Build; |
| 10 | import android.os.Environment; | 11 | import android.os.Environment; |
| @@ -14,6 +15,9 @@ import android.util.Log; | @@ -14,6 +15,9 @@ import android.util.Log; | ||
| 14 | import android.webkit.MimeTypeMap; | 15 | import android.webkit.MimeTypeMap; |
| 15 | 16 | ||
| 16 | import java.io.File; | 17 | import java.io.File; |
| 18 | +import java.io.FileOutputStream; | ||
| 19 | +import java.io.IOException; | ||
| 20 | +import java.util.UUID; | ||
| 17 | 21 | ||
| 18 | /** | 22 | /** |
| 19 | * Created by Lynn on 6/28/2017. | 23 | * Created by Lynn on 6/28/2017. |
| @@ -289,4 +293,53 @@ public class FileUtils { | @@ -289,4 +293,53 @@ public class FileUtils { | ||
| 289 | return ""; | 293 | return ""; |
| 290 | } | 294 | } |
| 291 | } | 295 | } |
| 296 | + | ||
| 297 | + private static final String SD_PATH = "/sdcard/cn_sv_cover_img"; | ||
| 298 | + private static final String IN_PATH = "/dskqxt/pic/"; | ||
| 299 | + | ||
| 300 | + /** | ||
| 301 | + * 随机生产文件名 | ||
| 302 | + * | ||
| 303 | + * @return | ||
| 304 | + */ | ||
| 305 | + private static String generateFileName() { | ||
| 306 | + return UUID.randomUUID().toString(); | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + /** | ||
| 310 | + * 保存bitmap到本地 | ||
| 311 | + * | ||
| 312 | + * @param context | ||
| 313 | + * @param mBitmap | ||
| 314 | + * @return | ||
| 315 | + */ | ||
| 316 | + public static String saveBitmap(Context context, Bitmap mBitmap) { | ||
| 317 | + String savePath; | ||
| 318 | + File filePic; | ||
| 319 | + if (Environment.getExternalStorageState().equals( | ||
| 320 | + Environment.MEDIA_MOUNTED)) { | ||
| 321 | + savePath = SD_PATH; | ||
| 322 | + } else { | ||
| 323 | + savePath = context.getApplicationContext().getFilesDir() | ||
| 324 | + .getAbsolutePath() | ||
| 325 | + + IN_PATH; | ||
| 326 | + } | ||
| 327 | + try { | ||
| 328 | + filePic = new File(savePath + generateFileName() + ".png"); | ||
| 329 | + if (!filePic.exists()) { | ||
| 330 | + filePic.getParentFile().mkdirs(); | ||
| 331 | + filePic.createNewFile(); | ||
| 332 | + } | ||
| 333 | + FileOutputStream fos = new FileOutputStream(filePic); | ||
| 334 | + mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); | ||
| 335 | + fos.flush(); | ||
| 336 | + fos.close(); | ||
| 337 | + } catch (IOException e) { | ||
| 338 | + // TODO Auto-generated catch block | ||
| 339 | + e.printStackTrace(); | ||
| 340 | + return null; | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + return filePic.getAbsolutePath(); | ||
| 344 | + } | ||
| 292 | } | 345 | } |
app/src/main/java/com/cnlive/demo/shortvideo/network/HttpRequest.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.network; | ||
| 2 | + | ||
| 3 | +import android.provider.ContactsContract; | ||
| 4 | +import android.text.TextUtils; | ||
| 5 | +import android.util.Log; | ||
| 6 | + | ||
| 7 | +import com.cnlive.demo.shortvideo.network.model.ShortVideoDataModel; | ||
| 8 | +import com.cnlive.demo.shortvideo.network.model.ShortVideoInfo; | ||
| 9 | +import com.cnlive.demo.shortvideo.network.util.SignUtil; | ||
| 10 | +import com.cnlive.libs.shortvideo.callback.Callback; | ||
| 11 | +import com.cnlive.libs.shortvideo.kit.base.ICNEditKit; | ||
| 12 | +import com.cnlive.libs.util.Config; | ||
| 13 | +import com.cnlive.libs.util.HttpUtils; | ||
| 14 | +import com.cnlive.libs.util.NetUtil; | ||
| 15 | +import com.cnlive.libs.util.data.okhttp3.Call; | ||
| 16 | +import com.cnlive.libs.util.data.okhttpUtil.callback.GenericsCallback; | ||
| 17 | + | ||
| 18 | +import java.util.HashMap; | ||
| 19 | +import java.util.Map; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Created by Lynn on 2017/7/19. | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | +public class HttpRequest { | ||
| 26 | + private static final String BASE_URL_RELEASE = "http://api.cnlive.com/open/api2"; | ||
| 27 | + | ||
| 28 | + private static final String BASE_URL_DEBUG = "http://test.open.cnlive.com/openapi/api2"; | ||
| 29 | + | ||
| 30 | + private static final String BASE_URL = Config.debug ? BASE_URL_DEBUG : BASE_URL_RELEASE; | ||
| 31 | + | ||
| 32 | + private static final String VIDEO_LIST = BASE_URL + "/vod_epg/sp/shortVideoList4APP"; | ||
| 33 | + | ||
| 34 | + private static DataGenericsCallback<ShortVideoDataModel> mShortVideoListCallback; | ||
| 35 | + | ||
| 36 | + private static abstract class DataGenericsCallback<T> extends GenericsCallback<T> { | ||
| 37 | + com.cnlive.libs.shortvideo.callback.Callback callback; | ||
| 38 | + | ||
| 39 | + DataGenericsCallback(Callback callback) { | ||
| 40 | + this.callback = callback; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + void cancel() { | ||
| 44 | + callback = null; | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + private static void videoList(String userId, | ||
| 49 | + String page, | ||
| 50 | + String pageSize, | ||
| 51 | + GenericsCallback<ShortVideoDataModel> callback) { | ||
| 52 | + Map<String, String> params = new HashMap<>(); | ||
| 53 | + params.put("appId", Config.getAppId()); | ||
| 54 | + params.put("userId", userId); | ||
| 55 | + params.put("page", page); | ||
| 56 | + params.put("pageSize", pageSize); | ||
| 57 | + params.put("platform_id", Config.getContext().getPackageName()); | ||
| 58 | + params.put("timestamp", String.valueOf(System.currentTimeMillis())); | ||
| 59 | + HttpUtils.doGetAsyn(VIDEO_LIST, SignUtil.getSignParamM(Config.getContext(), params), callback); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public static void getVideoList(String userId, | ||
| 63 | + String page, | ||
| 64 | + String pageSize, | ||
| 65 | + Callback callback) { | ||
| 66 | + if (mShortVideoListCallback != null) { | ||
| 67 | + mShortVideoListCallback.cancel(); | ||
| 68 | + mShortVideoListCallback = null; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + mShortVideoListCallback = new DataGenericsCallback<ShortVideoDataModel>(callback) { | ||
| 72 | + @Override | ||
| 73 | + public void onError(Call call, Exception e) { | ||
| 74 | + if (callback == null) return; | ||
| 75 | + if (!NetUtil.checkNetwork(Config.getContext())) { | ||
| 76 | + callback.onError(-10000, "网络连接失败"); | ||
| 77 | + } else { | ||
| 78 | + callback.onError(-10001, "其他错误"); | ||
| 79 | + } | ||
| 80 | + if (e != null) { | ||
| 81 | + Log.e("LynnTest", e.toString()); | ||
| 82 | + e.printStackTrace(); | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + @Override | ||
| 87 | + public void onResponse(ShortVideoDataModel shortVideoInfo, Exception e) { | ||
| 88 | + if (callback == null) return; | ||
| 89 | + if (shortVideoInfo != null && "0".equals(shortVideoInfo.getErrorCode())) { | ||
| 90 | + callback.onInfo(ICNEditKit.INFO_GET_UPLOAD_INFO_SUCCESS, shortVideoInfo); | ||
| 91 | + } else if (shortVideoInfo != null && !TextUtils.isEmpty(shortVideoInfo.getErrorCode())) { | ||
| 92 | + callback.onError(ICNEditKit.ERROR_GET_UPLOAD_INFO_SERVER, ICNEditKit.MSG_GET_UPLOAD_INFO_SERVER + shortVideoInfo.getErrorMessage()); | ||
| 93 | + } else { | ||
| 94 | + onError(null, e); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + }; | ||
| 98 | + | ||
| 99 | + videoList(userId, page, pageSize, mShortVideoListCallback); | ||
| 100 | + | ||
| 101 | + } | ||
| 102 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/network/model/ShortVideoDataModel.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.network.model; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +import com.cnlive.libs.shortvideo.network.model.ErrorMessage; | ||
| 5 | + | ||
| 6 | +import java.io.Serializable; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * Created by Lynn on 2017/7/13. | ||
| 10 | + */ | ||
| 11 | + | ||
| 12 | +public class ShortVideoDataModel extends ErrorMessage{ | ||
| 13 | + | ||
| 14 | + private ShortVideoList data; | ||
| 15 | + | ||
| 16 | + public ShortVideoList getData() { | ||
| 17 | + return data; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public void setData(ShortVideoList data) { | ||
| 21 | + this.data = data; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public String toString() { | ||
| 26 | + return "ShortVideoDataModel{" + | ||
| 27 | + "data=" + data + | ||
| 28 | + '}'; | ||
| 29 | + } | ||
| 30 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/network/model/ShortVideoInfo.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.network.model; | ||
| 2 | + | ||
| 3 | +import com.cnlive.libs.util.model.BaseData; | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * Created by Lynn on 2017/7/14. | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +public class ShortVideoInfo extends BaseData { | ||
| 11 | +// private String appId; | ||
| 12 | +// private String createTime; | ||
| 13 | + private String description; | ||
| 14 | +// private String id; | ||
| 15 | +// private String md5; | ||
| 16 | + private String name; | ||
| 17 | + private String picKey; | ||
| 18 | +// private String path; | ||
| 19 | +// private String spId; | ||
| 20 | + private String status; | ||
| 21 | +// private String updateTime; | ||
| 22 | + private String videoId; | ||
| 23 | + | ||
| 24 | +// public String getAppId() { | ||
| 25 | +// return appId; | ||
| 26 | +// } | ||
| 27 | +// | ||
| 28 | +// public void setAppId(String appId) { | ||
| 29 | +// this.appId = appId; | ||
| 30 | +// } | ||
| 31 | +// | ||
| 32 | +// public String getCreateTime() { | ||
| 33 | +// if (createTime != null) { | ||
| 34 | +// return DateUtils.getDateToString(Long.parseLong(createTime)); | ||
| 35 | +// }else { | ||
| 36 | +// return ""; | ||
| 37 | +// } | ||
| 38 | +// } | ||
| 39 | +// | ||
| 40 | +// public void setCreateTime(String createTime) { | ||
| 41 | +// this.createTime = createTime; | ||
| 42 | +// } | ||
| 43 | + | ||
| 44 | + public String getDescription() { | ||
| 45 | + return description; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public void setDescription(String description) { | ||
| 49 | + this.description = description; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | +// public String getId() { | ||
| 53 | +// return id; | ||
| 54 | +// } | ||
| 55 | +// | ||
| 56 | +// public void setId(String id) { | ||
| 57 | +// this.id = id; | ||
| 58 | +// } | ||
| 59 | +// | ||
| 60 | +// public String getMd5() { | ||
| 61 | +// return md5; | ||
| 62 | +// } | ||
| 63 | +// | ||
| 64 | +// public void setMd5(String md5) { | ||
| 65 | +// this.md5 = md5; | ||
| 66 | +// } | ||
| 67 | + | ||
| 68 | + public String getName() { | ||
| 69 | + return name; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + public void setName(String name) { | ||
| 73 | + this.name = name; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + public String getPicKey() { | ||
| 77 | + return picKey; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + public void setPicKey(String picKey) { | ||
| 81 | + this.picKey = picKey; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + // public String getPath() { | ||
| 85 | +// return path; | ||
| 86 | +// } | ||
| 87 | +// | ||
| 88 | +// public void setPath(String path) { | ||
| 89 | +// this.path = path; | ||
| 90 | +// } | ||
| 91 | +// | ||
| 92 | +// public String getSpId() { | ||
| 93 | +// return spId; | ||
| 94 | +// } | ||
| 95 | +// | ||
| 96 | +// public void setSpId(String spId) { | ||
| 97 | +// this.spId = spId; | ||
| 98 | +// } | ||
| 99 | + | ||
| 100 | + public String getStatus() { | ||
| 101 | + return status; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + public void setStatus(String status) { | ||
| 105 | + this.status = status; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | +// public String getUpdateTime() { | ||
| 109 | +// return updateTime; | ||
| 110 | +// } | ||
| 111 | +// | ||
| 112 | +// public void setUpdateTime(String updateTime) { | ||
| 113 | +// this.updateTime = updateTime; | ||
| 114 | +// } | ||
| 115 | + | ||
| 116 | + public String getVideoId() { | ||
| 117 | + return videoId; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + public void setVideoId(String videoId) { | ||
| 121 | + this.videoId = videoId; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + @Override | ||
| 125 | + public String toString() { | ||
| 126 | + return "ShortVideoInfo{" + | ||
| 127 | + "description='" + description + '\'' + | ||
| 128 | + ", name='" + name + '\'' + | ||
| 129 | + ", picKey='" + picKey + '\'' + | ||
| 130 | + ", status='" + status + '\'' + | ||
| 131 | + ", videoId='" + videoId + '\'' + | ||
| 132 | + '}'; | ||
| 133 | + } | ||
| 134 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/network/model/ShortVideoList.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.network.model; | ||
| 2 | + | ||
| 3 | +import com.cnlive.libs.util.model.BaseData; | ||
| 4 | + | ||
| 5 | +import java.io.Serializable; | ||
| 6 | +import java.util.List; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * Created by Lynn on 2017/7/14. | ||
| 10 | + */ | ||
| 11 | + | ||
| 12 | +public class ShortVideoList extends BaseData{ | ||
| 13 | + List<ShortVideoInfo> list; | ||
| 14 | + | ||
| 15 | + public List<ShortVideoInfo> getList() { | ||
| 16 | + return list; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public void setList(List<ShortVideoInfo> list) { | ||
| 20 | + this.list = list; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + @Override | ||
| 24 | + public String toString() { | ||
| 25 | + return "ShortVideoList{" + | ||
| 26 | + "list=" + list + | ||
| 27 | + '}'; | ||
| 28 | + } | ||
| 29 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/network/util/SignUtil.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.network.util; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.util.Log; | ||
| 5 | + | ||
| 6 | +import com.cnlive.libs.util.Config; | ||
| 7 | +import com.cnlive.libs.util.SHA1; | ||
| 8 | + | ||
| 9 | +import java.io.UnsupportedEncodingException; | ||
| 10 | +import java.net.URLEncoder; | ||
| 11 | +import java.util.ArrayList; | ||
| 12 | +import java.util.Collections; | ||
| 13 | +import java.util.Comparator; | ||
| 14 | +import java.util.HashMap; | ||
| 15 | +import java.util.LinkedHashMap; | ||
| 16 | +import java.util.List; | ||
| 17 | +import java.util.Locale; | ||
| 18 | +import java.util.Map; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * Created by Lynn on 5/25/2017. | ||
| 22 | + */ | ||
| 23 | + | ||
| 24 | +public class SignUtil { | ||
| 25 | + //时间服务器地址 | ||
| 26 | + private static final String URL_TIME_SERVICE = "https://api.cnlive.com/open/api2/timestamp"; | ||
| 27 | + | ||
| 28 | + private static final String TAG = "SignUtil"; | ||
| 29 | + | ||
| 30 | + public static Map<String, String> getSignParamM(Context context, Map<String, String> params) { | ||
| 31 | + if (context == null || params == null) return new HashMap<>(); | ||
| 32 | + params.put("platform_id", context.getPackageName()); | ||
| 33 | + params.put("timestamp", String.valueOf(getTime() / 1000)); | ||
| 34 | + Map<String, String> map = order(params); | ||
| 35 | + if (map.containsKey("sign")) { | ||
| 36 | + map.remove("sign"); | ||
| 37 | + } | ||
| 38 | + String signValue = SHA1 | ||
| 39 | + .SHA1Digest(mapJoin(map, false).concat("&key=").concat(Config.getSpKey())) | ||
| 40 | + .toUpperCase(Locale.getDefault()); | ||
| 41 | + map.put("sign", signValue); | ||
| 42 | + return map; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + private static String getSignParam(Context context, Map<String, String> params) { | ||
| 46 | + if (context == null || params == null) return ""; | ||
| 47 | + params.put("platform_id", context.getPackageName()); | ||
| 48 | + params.put("timestamp", String.valueOf(getTime() / 1000)); | ||
| 49 | + | ||
| 50 | + String signParam = mapParam(params); | ||
| 51 | + | ||
| 52 | + Map<String, String> map = order(params); | ||
| 53 | + | ||
| 54 | + if (map.containsKey("sign")) { | ||
| 55 | + map.remove("sign"); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + String signValue = SHA1.SHA1Digest(mapJoin(map, false).concat("&key=").concat(Config.getSpKey())) | ||
| 59 | + .toUpperCase(Locale.getDefault()); | ||
| 60 | + return signParam.concat("&sign=").concat(signValue); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + private static long getTime() { | ||
| 64 | +// OkHttpClient okHttpClient = new OkHttpClient(); | ||
| 65 | +// try { | ||
| 66 | +// Request request = new Request.Builder().url(URL_TIME_SERVICE).build(); | ||
| 67 | +// Response response = okHttpClient.newCall(request).execute(); | ||
| 68 | +// Headers headers = response.headers(); | ||
| 69 | +// | ||
| 70 | +// Date date = headers.getDate("Date"); | ||
| 71 | +// return date == null ? System.currentTimeMillis() : date.getTime(); | ||
| 72 | +// } catch (Exception e) { | ||
| 73 | +// e.printStackTrace(); | ||
| 74 | +// } | ||
| 75 | + | ||
| 76 | + return System.currentTimeMillis(); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + public static String mapParam(Map<String, String> map) { | ||
| 80 | + StringBuilder stringBuilder = new StringBuilder(); | ||
| 81 | + for (String key : map.keySet()) { | ||
| 82 | + stringBuilder.append(key).append("=").append(map.get(key)).append("&"); | ||
| 83 | + } | ||
| 84 | + if (stringBuilder.length() > 0) { | ||
| 85 | + stringBuilder.deleteCharAt(stringBuilder.length() - 1); | ||
| 86 | + } | ||
| 87 | + return stringBuilder.toString(); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + private static Map<String, String> order(Map<String, String> map) { | ||
| 91 | + HashMap<String, String> tempMap = new LinkedHashMap<>(); | ||
| 92 | + List<Map.Entry<String, String>> infoIds = new ArrayList<>(map.entrySet()); | ||
| 93 | + | ||
| 94 | + Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() { | ||
| 95 | + public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { | ||
| 96 | + return o1.getKey().compareTo(o2.getKey()); | ||
| 97 | + } | ||
| 98 | + }); | ||
| 99 | + | ||
| 100 | + for (int i = 0; i < infoIds.size(); i++) { | ||
| 101 | + Map.Entry<String, String> item = infoIds.get(i); | ||
| 102 | + tempMap.put(item.getKey(), item.getValue()); | ||
| 103 | + } | ||
| 104 | + return tempMap; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + private static String mapJoin(Map<String, String> map, boolean valueUrlencode) { | ||
| 108 | + StringBuilder stringBuilder = new StringBuilder(); | ||
| 109 | + for (String key : map.keySet()) { | ||
| 110 | + if (map.get(key) != null && !"".equals(map.get(key))) { | ||
| 111 | + try { | ||
| 112 | + stringBuilder.append(key) | ||
| 113 | + .append("=") | ||
| 114 | + .append(valueUrlencode ? URLEncoder.encode(map.get(key), "utf-8").replace("+", "%20") : map.get(key)) | ||
| 115 | + .append("&"); | ||
| 116 | + } catch (UnsupportedEncodingException e) { | ||
| 117 | + Log.e(TAG, "Load:" + e.getMessage(), e); | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + if (stringBuilder.length() > 0) { | ||
| 122 | + stringBuilder.deleteCharAt(stringBuilder.length() - 1); | ||
| 123 | + } | ||
| 124 | + return stringBuilder.toString(); | ||
| 125 | + } | ||
| 126 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/ui/activity/EditActivity.java
| @@ -49,6 +49,7 @@ import android.widget.TextView; | @@ -49,6 +49,7 @@ import android.widget.TextView; | ||
| 49 | import android.widget.Toast; | 49 | import android.widget.Toast; |
| 50 | 50 | ||
| 51 | import com.cnlive.demo.shortvideo.R; | 51 | import com.cnlive.demo.shortvideo.R; |
| 52 | +import com.cnlive.demo.shortvideo.file.FileUtils; | ||
| 52 | import com.cnlive.demo.shortvideo.ui.dialog.ShortVideoConfigDialog; | 53 | import com.cnlive.demo.shortvideo.ui.dialog.ShortVideoConfigDialog; |
| 53 | import com.cnlive.demo.shortvideo.sticker.StickerAdapter; | 54 | import com.cnlive.demo.shortvideo.sticker.StickerAdapter; |
| 54 | import com.cnlive.demo.shortvideo.util.ColorPicker; | 55 | import com.cnlive.demo.shortvideo.util.ColorPicker; |
| @@ -938,7 +939,7 @@ public class EditActivity extends AppCompatActivity implements ActivityCompat.On | @@ -938,7 +939,7 @@ public class EditActivity extends AppCompatActivity implements ActivityCompat.On | ||
| 938 | mComposeAlertDialog.composeFinished(strings[0]); | 939 | mComposeAlertDialog.composeFinished(strings[0]); |
| 939 | mComposeFinished = true; | 940 | mComposeFinished = true; |
| 940 | } | 941 | } |
| 941 | - mEditKit.getUploadInfo(strings[0],"title.mp4", "des", mPutObjectResponseListener); | 942 | + mEditKit.getUploadInfo("1342671", strings[0], "title.mp4", "des", new File(FileUtils.saveBitmap(EditActivity.this, bitmap)), null, mPutObjectResponseListener); |
| 942 | } | 943 | } |
| 943 | case ShortVideoConstants.SHORTVIDEO_COMPOSE_ABORTED: | 944 | case ShortVideoConstants.SHORTVIDEO_COMPOSE_ABORTED: |
| 944 | break; | 945 | break; |
| @@ -1695,7 +1696,7 @@ public class EditActivity extends AppCompatActivity implements ActivityCompat.On | @@ -1695,7 +1696,7 @@ public class EditActivity extends AppCompatActivity implements ActivityCompat.On | ||
| 1695 | } catch (Exception e) { | 1696 | } catch (Exception e) { |
| 1696 | e.printStackTrace(); | 1697 | e.printStackTrace(); |
| 1697 | } | 1698 | } |
| 1698 | - }else { | 1699 | + } else { |
| 1699 | mMediaPlayer.setDataSource(new IDataSource() { | 1700 | mMediaPlayer.setDataSource(new IDataSource() { |
| 1700 | @Override | 1701 | @Override |
| 1701 | public String getDataSourceId() { | 1702 | public String getDataSourceId() { |
app/src/main/java/com/cnlive/demo/shortvideo/ui/activity/ListVideoActivity.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.ui.activity; | ||
| 2 | + | ||
| 3 | +import android.support.v4.widget.SwipeRefreshLayout; | ||
| 4 | +import android.support.v7.app.AppCompatActivity; | ||
| 5 | +import android.os.Bundle; | ||
| 6 | +import android.support.v7.widget.LinearLayoutManager; | ||
| 7 | +import android.support.v7.widget.RecyclerView; | ||
| 8 | +import android.util.Log; | ||
| 9 | +import android.view.View; | ||
| 10 | +import android.widget.TextView; | ||
| 11 | +import android.widget.Toast; | ||
| 12 | + | ||
| 13 | +import com.cnlive.demo.shortvideo.R; | ||
| 14 | +import com.cnlive.demo.shortvideo.network.HttpRequest; | ||
| 15 | +import com.cnlive.demo.shortvideo.network.model.ShortVideoDataModel; | ||
| 16 | +import com.cnlive.demo.shortvideo.ui.adapter.ShortVideoAdapter; | ||
| 17 | +import com.cnlive.libs.shortvideo.callback.Callback; | ||
| 18 | +import com.cnlive.libs.util.HttpUtils; | ||
| 19 | + | ||
| 20 | +public class ListVideoActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener { | ||
| 21 | + | ||
| 22 | + private RecyclerView videoList; | ||
| 23 | + private TextView emptyView; | ||
| 24 | + private SwipeRefreshLayout swipeRefreshLayout; | ||
| 25 | + private ShortVideoAdapter shortVideoAdapter; | ||
| 26 | + private LinearLayoutManager mLayoutManager; | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 30 | + super.onCreate(savedInstanceState); | ||
| 31 | + setContentView(R.layout.activity_list_video); | ||
| 32 | + initView(); | ||
| 33 | + loadData(); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + private void initView() { | ||
| 37 | + videoList = (RecyclerView) findViewById(R.id.recycler_view); | ||
| 38 | + emptyView = (TextView) findViewById(R.id.empty_view); | ||
| 39 | + swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.contentView); | ||
| 40 | + swipeRefreshLayout.setOnRefreshListener(this); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + private void loadData() { | ||
| 44 | + HttpRequest.getVideoList("1342671", "1", "15", new Callback() { | ||
| 45 | + @Override | ||
| 46 | + public void onError(int i, String s) { | ||
| 47 | + swipeRefreshLayout.setRefreshing(false); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + @Override | ||
| 51 | + public void onInfo(final int i, Object o) { | ||
| 52 | + swipeRefreshLayout.setRefreshing(false); | ||
| 53 | + final ShortVideoDataModel model = (ShortVideoDataModel) o; | ||
| 54 | + if (model.getData() == null) { | ||
| 55 | + videoList.setVisibility(View.GONE); | ||
| 56 | + emptyView.setVisibility(View.VISIBLE); | ||
| 57 | + } else { | ||
| 58 | + mLayoutManager = new LinearLayoutManager(ListVideoActivity.this); | ||
| 59 | + videoList.setLayoutManager(mLayoutManager); | ||
| 60 | + videoList.setHasFixedSize(true); | ||
| 61 | + shortVideoAdapter = new ShortVideoAdapter(ListVideoActivity.this, model.getData().getList()); | ||
| 62 | + videoList.setAdapter(shortVideoAdapter); | ||
| 63 | + shortVideoAdapter.setOnItemClickListener(new ShortVideoAdapter.OnItemClickListener() { | ||
| 64 | + @Override | ||
| 65 | + public void onItemClick(View view, int position) { | ||
| 66 | + String videoId = model.getData().getList().get(position).getVideoId(); | ||
| 67 | + String title = model.getData().getList().get(position).getName(); | ||
| 68 | + String des = model.getData().getList().get(position).getDescription(); | ||
| 69 | + Toast.makeText(ListVideoActivity.this, "点击 " + position, Toast.LENGTH_SHORT).show(); | ||
| 70 | + ShortVideoPlayActivity.startActivity(ListVideoActivity.this, videoId, title, des); | ||
| 71 | + } | ||
| 72 | + }); | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + }); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + @Override | ||
| 79 | + public void onRefresh() { | ||
| 80 | + loadData(); | ||
| 81 | + } | ||
| 82 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/ui/activity/MainActivity.java
| 1 | package com.cnlive.demo.shortvideo.ui.activity; | 1 | package com.cnlive.demo.shortvideo.ui.activity; |
| 2 | 2 | ||
| 3 | import android.content.DialogInterface; | 3 | import android.content.DialogInterface; |
| 4 | +import android.content.Intent; | ||
| 4 | import android.os.Handler; | 5 | import android.os.Handler; |
| 5 | import android.support.v7.app.AppCompatActivity; | 6 | import android.support.v7.app.AppCompatActivity; |
| 6 | import android.os.Bundle; | 7 | import android.os.Bundle; |
| @@ -21,6 +22,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | @@ -21,6 +22,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | ||
| 21 | private Button mAuthButton; | 22 | private Button mAuthButton; |
| 22 | private Button mRecordButton; | 23 | private Button mRecordButton; |
| 23 | private Button mImportFileButton; | 24 | private Button mImportFileButton; |
| 25 | + private Button mVideoListButton; | ||
| 24 | 26 | ||
| 25 | private Handler mMainHandler; | 27 | private Handler mMainHandler; |
| 26 | 28 | ||
| @@ -40,6 +42,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | @@ -40,6 +42,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | ||
| 40 | mRecordButton.setOnClickListener(this); | 42 | mRecordButton.setOnClickListener(this); |
| 41 | mImportFileButton = (Button) findViewById(R.id.import_file); | 43 | mImportFileButton = (Button) findViewById(R.id.import_file); |
| 42 | mImportFileButton.setOnClickListener(this); | 44 | mImportFileButton.setOnClickListener(this); |
| 45 | + mVideoListButton = (Button) findViewById(R.id.video_list); | ||
| 46 | + mVideoListButton.setOnClickListener(this); | ||
| 43 | } | 47 | } |
| 44 | 48 | ||
| 45 | @Override | 49 | @Override |
| @@ -65,6 +69,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | @@ -65,6 +69,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | ||
| 65 | case R.id.import_file: | 69 | case R.id.import_file: |
| 66 | onImportFileClick(); | 70 | onImportFileClick(); |
| 67 | break; | 71 | break; |
| 72 | + case R.id.video_list: | ||
| 73 | + onVideoListClick(); | ||
| 74 | + break; | ||
| 68 | } | 75 | } |
| 69 | } | 76 | } |
| 70 | 77 | ||
| @@ -139,4 +146,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | @@ -139,4 +146,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe | ||
| 139 | private void onImportFileClick() { | 146 | private void onImportFileClick() { |
| 140 | FileImportActivity.startActivity(MainActivity.this, "/sdcard/uncle.mp4"); | 147 | FileImportActivity.startActivity(MainActivity.this, "/sdcard/uncle.mp4"); |
| 141 | } | 148 | } |
| 149 | + | ||
| 150 | + private void onVideoListClick() { | ||
| 151 | + Intent intent = new Intent(this, ListVideoActivity.class); | ||
| 152 | + startActivity(intent); | ||
| 153 | + } | ||
| 142 | } | 154 | } |
app/src/main/java/com/cnlive/demo/shortvideo/ui/activity/ShortVideoPlayActivity.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.ui.activity; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.content.Intent; | ||
| 5 | +import android.os.Bundle; | ||
| 6 | +import android.os.Handler; | ||
| 7 | +import android.os.Message; | ||
| 8 | +import android.support.v7.app.AppCompatActivity; | ||
| 9 | +import android.util.Log; | ||
| 10 | +import android.view.KeyEvent; | ||
| 11 | +import android.view.MotionEvent; | ||
| 12 | +import android.view.View; | ||
| 13 | +import android.widget.ImageView; | ||
| 14 | +import android.widget.LinearLayout; | ||
| 15 | +import android.widget.SeekBar; | ||
| 16 | +import android.widget.TextView; | ||
| 17 | + | ||
| 18 | +import com.cnlive.demo.shortvideo.R; | ||
| 19 | +import com.cnlive.libs.util.Config; | ||
| 20 | +import com.cnlive.libs.video.video.MediaPlayer; | ||
| 21 | +import com.cnlive.libs.video.video.VideoView; | ||
| 22 | +import com.cnlive.libs.video.video.base.IDataSource; | ||
| 23 | +import com.cnlive.libs.video.video.base.IMediaPlayer; | ||
| 24 | + | ||
| 25 | +import java.text.DecimalFormat; | ||
| 26 | +import java.text.NumberFormat; | ||
| 27 | +import java.util.Locale; | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +public class ShortVideoPlayActivity extends AppCompatActivity { | ||
| 31 | + private static final String TAG = "VideoPlayerActivity"; | ||
| 32 | + | ||
| 33 | + public static final int UPDATE_SEEKBAR = 0; | ||
| 34 | + public static final int HIDDEN_SEEKBAR = 1; | ||
| 35 | + | ||
| 36 | + private Context mContext; | ||
| 37 | + private VideoView mVideoView; | ||
| 38 | + private LinearLayout mPlayerPanel; | ||
| 39 | + private ImageView mPlayerStartBtn; | ||
| 40 | + private SeekBar mPlayerSeekbar; | ||
| 41 | + private TextView mPlayerPosition; | ||
| 42 | + private TextView mLoadText; | ||
| 43 | + private TextView mPlayerTitle; | ||
| 44 | + private TextView mPlayerDes; | ||
| 45 | + | ||
| 46 | + private LinearLayout toppanel; | ||
| 47 | + | ||
| 48 | + private boolean mPlayerPanelShow = false; | ||
| 49 | + private boolean mPause = false; | ||
| 50 | + | ||
| 51 | + private int mVideoWidth = 0; | ||
| 52 | + private int mVideoHeight = 0; | ||
| 53 | + | ||
| 54 | + private Handler mHandler; | ||
| 55 | + | ||
| 56 | + private final static String VIDEO_ID = "videoId"; | ||
| 57 | + private final static String NAME = "name"; | ||
| 58 | + private final static String DES = "des"; | ||
| 59 | + private String videoId; | ||
| 60 | + private String name; | ||
| 61 | + private String des; | ||
| 62 | + | ||
| 63 | + public static void startActivity(Context context, String videoId, String name, String des) { | ||
| 64 | + Intent intent = new Intent(context, ShortVideoPlayActivity.class); | ||
| 65 | + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||
| 66 | + intent.putExtra(VIDEO_ID, videoId); | ||
| 67 | + intent.putExtra(NAME, name); | ||
| 68 | + intent.putExtra(DES, des); | ||
| 69 | + context.startActivity(intent); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + @Override | ||
| 73 | + protected void onCreate(Bundle savedInstanceState) { | ||
| 74 | + super.onCreate(savedInstanceState); | ||
| 75 | + mContext = this.getApplicationContext(); | ||
| 76 | + setContentView(R.layout.activity_short_video_play); | ||
| 77 | + initData(); | ||
| 78 | + initView(); | ||
| 79 | + initVideoView(); | ||
| 80 | + | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + private void initData() { | ||
| 84 | + Bundle bundle = getIntent().getExtras(); | ||
| 85 | + videoId = bundle.getString(VIDEO_ID); | ||
| 86 | + name = bundle.getString(NAME); | ||
| 87 | + des = bundle.getString(DES); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + private void initVideoView() { | ||
| 91 | + mHandler = new Handler() { | ||
| 92 | + @Override | ||
| 93 | + public void handleMessage(Message msg) { | ||
| 94 | + super.handleMessage(msg); | ||
| 95 | + switch (msg.what) { | ||
| 96 | + case UPDATE_SEEKBAR: | ||
| 97 | + setVideoProgress(0); | ||
| 98 | + break; | ||
| 99 | + case HIDDEN_SEEKBAR: | ||
| 100 | + mPlayerPanelShow = false; | ||
| 101 | + mPlayerPanel.setVisibility(View.GONE); | ||
| 102 | + toppanel.setVisibility(View.GONE); | ||
| 103 | + break; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + } | ||
| 107 | + }; | ||
| 108 | + mVideoView.setOnPreparedListener(mOnPreparedListener); | ||
| 109 | + mVideoView.setOnCompletionListener(mOnCompletionListener); | ||
| 110 | + mVideoView.setOnErrorListener(mOnErrorListener); | ||
| 111 | + mVideoView.setOnInfoListener(mOnInfoListener); | ||
| 112 | + mVideoView.setOnPlayStateListener(mOnPlayStateListener); | ||
| 113 | + mVideoView.setOnBufferingUpdateListener(mOnBufferingUpdateListener); | ||
| 114 | + mVideoView.setOnVideoSizeChangedListener(mOnVideoSizeChangeListener); | ||
| 115 | + mVideoView.setOnTouchListener(mTouchListener); | ||
| 116 | + | ||
| 117 | + mVideoView.setDataSource(new IDataSource() { | ||
| 118 | + @Override | ||
| 119 | + public String getDataSourceId() { | ||
| 120 | + return videoId; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + @Override | ||
| 124 | + public String getDataSourceType() { | ||
| 125 | + return Config.TYPE_VOD; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + @Override | ||
| 129 | + public String getDataSourceRate() { | ||
| 130 | + return Config.TYPE_PLAY_RATE_2; | ||
| 131 | + } | ||
| 132 | + }); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Override | ||
| 136 | + protected void onDestroy() { | ||
| 137 | + super.onDestroy(); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + @Override | ||
| 141 | + protected void onPause() { | ||
| 142 | + super.onPause(); | ||
| 143 | + | ||
| 144 | + if (mVideoView != null) { | ||
| 145 | + mVideoView.pause(); | ||
| 146 | + mPause = true; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + @Override | ||
| 151 | + protected void onResume() { | ||
| 152 | + super.onResume(); | ||
| 153 | + if (mVideoView != null) { | ||
| 154 | + mVideoView.start(); | ||
| 155 | + mPause = false; | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + @Override | ||
| 160 | + public boolean onKeyDown(int keyCode, KeyEvent event) { | ||
| 161 | + if (keyCode == KeyEvent.KEYCODE_BACK) { | ||
| 162 | + videoPlayEnd(); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + return super.onKeyDown(keyCode, event); | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + private void initView() { | ||
| 169 | + mVideoView = (VideoView) findViewById(R.id.video_view); | ||
| 170 | + mPlayerPanel = (LinearLayout) findViewById(R.id.player_panel); | ||
| 171 | + mPlayerStartBtn = (ImageView) findViewById(R.id.player_start); | ||
| 172 | + mPlayerSeekbar = (SeekBar) findViewById(R.id.player_seekbar); | ||
| 173 | + mPlayerPosition = (TextView) findViewById(R.id.player_time); | ||
| 174 | + mLoadText = (TextView) findViewById(R.id.loading_text); | ||
| 175 | + toppanel = (LinearLayout) findViewById(R.id.top_player_panel); | ||
| 176 | + mPlayerTitle = (TextView) findViewById(R.id.video_title); | ||
| 177 | + mPlayerDes = (TextView) findViewById(R.id.video_description); | ||
| 178 | + mPlayerTitle.setText(name); | ||
| 179 | + mPlayerDes.setText(des); | ||
| 180 | + mPlayerSeekbar.setOnSeekBarChangeListener(mSeekBarListener); | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + private MediaPlayer.OnPreparedListener mOnPreparedListener = new MediaPlayer.OnPreparedListener() { | ||
| 184 | + @Override | ||
| 185 | + public void onPrepared(IMediaPlayer mediaplayer) { | ||
| 186 | + mVideoWidth = mVideoView.getVideoWidth(); | ||
| 187 | + mVideoHeight = mVideoView.getVideoHeight(); | ||
| 188 | + | ||
| 189 | + // Set Video Scaling Mode | ||
| 190 | + mVideoView.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); | ||
| 191 | + | ||
| 192 | + //start player | ||
| 193 | + mVideoView.start(); | ||
| 194 | + | ||
| 195 | + //set progress | ||
| 196 | + setVideoProgress(0); | ||
| 197 | + | ||
| 198 | + mPlayerPosition.setVisibility(View.VISIBLE); | ||
| 199 | + mLoadText.setVisibility(View.VISIBLE); | ||
| 200 | + | ||
| 201 | + mHandler.removeMessages(HIDDEN_SEEKBAR); | ||
| 202 | + Message msg = new Message(); | ||
| 203 | + msg.what = HIDDEN_SEEKBAR; | ||
| 204 | + mHandler.sendMessageDelayed(msg, 3000); | ||
| 205 | + } | ||
| 206 | + }; | ||
| 207 | + | ||
| 208 | + private IMediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new IMediaPlayer.OnBufferingUpdateListener() { | ||
| 209 | + @Override | ||
| 210 | + public void onBufferingUpdate(IMediaPlayer mp, int percent) { | ||
| 211 | + long duration = mVideoView.getDuration(); | ||
| 212 | + long progress = duration * percent / 100; | ||
| 213 | + mPlayerSeekbar.setSecondaryProgress((int) progress); | ||
| 214 | + } | ||
| 215 | + }; | ||
| 216 | + | ||
| 217 | + private IMediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangeListener = new IMediaPlayer.OnVideoSizeChangedListener() { | ||
| 218 | + @Override | ||
| 219 | + public void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sarNum, int sarDen) { | ||
| 220 | + if (mVideoWidth > 0 && mVideoHeight > 0) { | ||
| 221 | + if (width != mVideoWidth || height != mVideoHeight) { | ||
| 222 | + mVideoWidth = mp.getVideoWidth(); | ||
| 223 | + mVideoHeight = mp.getVideoHeight(); | ||
| 224 | + | ||
| 225 | + if (mVideoView != null) | ||
| 226 | + mVideoView.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); | ||
| 227 | + } | ||
| 228 | + } | ||
| 229 | + } | ||
| 230 | + }; | ||
| 231 | + | ||
| 232 | + private IMediaPlayer.OnSeekCompleteListener mOnSeekCompletedListener = new IMediaPlayer.OnSeekCompleteListener() { | ||
| 233 | + @Override | ||
| 234 | + public void onSeekComplete(IMediaPlayer mp) { | ||
| 235 | + Log.e(TAG, "onSeekComplete..............."); | ||
| 236 | + } | ||
| 237 | + }; | ||
| 238 | + | ||
| 239 | + private IMediaPlayer.OnCompletionListener mOnCompletionListener = new IMediaPlayer.OnCompletionListener() { | ||
| 240 | + @Override | ||
| 241 | + public void onCompletion(IMediaPlayer mp) { | ||
| 242 | +// Toast.makeText(mContext, "OnCompletionListener, play complete.", Toast.LENGTH_LONG).show(); | ||
| 243 | + videoPlayEnd(); | ||
| 244 | + } | ||
| 245 | + }; | ||
| 246 | + | ||
| 247 | + private IMediaPlayer.OnErrorListener mOnErrorListener = new IMediaPlayer.OnErrorListener() { | ||
| 248 | + @Override | ||
| 249 | + public boolean onError(IMediaPlayer mp, int what, int extra) { | ||
| 250 | + switch (what) { | ||
| 251 | + case MediaPlayer.MEDIA_ERROR_UNKNOWN: | ||
| 252 | + Log.e(TAG, "OnErrorListener, Error Unknown:" + what + ",extra:" + extra); | ||
| 253 | + break; | ||
| 254 | + default: | ||
| 255 | + Log.e(TAG, "OnErrorListener, Error:" + what + ",extra:" + extra); | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + videoPlayEnd(); | ||
| 259 | + | ||
| 260 | + return false; | ||
| 261 | + } | ||
| 262 | + }; | ||
| 263 | + | ||
| 264 | + public IMediaPlayer.OnInfoListener mOnInfoListener = new IMediaPlayer.OnInfoListener() { | ||
| 265 | + @Override | ||
| 266 | + public boolean onInfo(IMediaPlayer iMediaPlayer, int i, int i1) { | ||
| 267 | + switch (i) { | ||
| 268 | + case MediaPlayer.MEDIA_INFO_BUFFERING_START: | ||
| 269 | + Log.d(TAG, "Buffering Start."); | ||
| 270 | + break; | ||
| 271 | + case MediaPlayer.MEDIA_INFO_BUFFERING_END: | ||
| 272 | + Log.d(TAG, "Buffering End."); | ||
| 273 | + break; | ||
| 274 | + case MediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START: | ||
| 275 | +// Toast.makeText(mContext, "Audio Rendering Start", Toast.LENGTH_SHORT).show(); | ||
| 276 | + break; | ||
| 277 | + case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: | ||
| 278 | +// Toast.makeText(mContext, "Video Rendering Start", Toast.LENGTH_SHORT).show(); | ||
| 279 | + break; | ||
| 280 | +// case MediaPlayer.MEDIA_INFO_SUGGEST_RELOAD: | ||
| 281 | +// // Player find a new stream(video or audio), and we could reload the video. | ||
| 282 | +// if (mVideoView != null) | ||
| 283 | +// mVideoView.reload(mDataSource, false); | ||
| 284 | +// break; | ||
| 285 | + case MediaPlayer.MEDIA_INFO_RELOADED: | ||
| 286 | +// Toast.makeText(mContext, "Succeed to reload video.", Toast.LENGTH_SHORT).show(); | ||
| 287 | + Log.d(TAG, "Succeed to reload video."); | ||
| 288 | + return false; | ||
| 289 | + } | ||
| 290 | + return false; | ||
| 291 | + } | ||
| 292 | + }; | ||
| 293 | + | ||
| 294 | + private View.OnTouchListener mTouchListener = new View.OnTouchListener() { | ||
| 295 | + @Override | ||
| 296 | + public boolean onTouch(View v, MotionEvent event) { | ||
| 297 | + dealTouchEvent(v, event); | ||
| 298 | + return false; | ||
| 299 | + } | ||
| 300 | + }; | ||
| 301 | + | ||
| 302 | + public IMediaPlayer.OnPlayStateListener mOnPlayStateListener = new IMediaPlayer.OnPlayStateListener() { | ||
| 303 | + @Override | ||
| 304 | + public void onPlayState(boolean played) { | ||
| 305 | + mPlayerStartBtn.setBackgroundResource(played ? R.drawable.pause : R.drawable.play); | ||
| 306 | + } | ||
| 307 | + }; | ||
| 308 | + | ||
| 309 | + private int mVideoProgress = 0; | ||
| 310 | + private SeekBar.OnSeekBarChangeListener mSeekBarListener = new SeekBar.OnSeekBarChangeListener() { | ||
| 311 | + @Override | ||
| 312 | + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | ||
| 313 | + if (fromUser) { | ||
| 314 | + mVideoProgress = progress; | ||
| 315 | + mHandler.removeMessages(HIDDEN_SEEKBAR); | ||
| 316 | + Message msg = new Message(); | ||
| 317 | + msg.what = HIDDEN_SEEKBAR; | ||
| 318 | + mHandler.sendMessageDelayed(msg, 3000); | ||
| 319 | + } | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + @Override | ||
| 323 | + public void onStartTrackingTouch(SeekBar seekBar) { | ||
| 324 | + | ||
| 325 | + } | ||
| 326 | + | ||
| 327 | + @Override | ||
| 328 | + public void onStopTrackingTouch(SeekBar seekBar) { | ||
| 329 | + mVideoView.seekTo(mVideoProgress); | ||
| 330 | + setVideoProgress(mVideoProgress); | ||
| 331 | + } | ||
| 332 | + }; | ||
| 333 | + | ||
| 334 | + | ||
| 335 | + public int setVideoProgress(int currentProgress) { | ||
| 336 | + | ||
| 337 | + if (mVideoView == null) | ||
| 338 | + return -1; | ||
| 339 | + | ||
| 340 | + long time = currentProgress > 0 ? currentProgress : mVideoView.getCurrentPosition(); | ||
| 341 | + long length = mVideoView.getDuration(); | ||
| 342 | + | ||
| 343 | + // Update all view elements | ||
| 344 | + mPlayerSeekbar.setMax((int) length); | ||
| 345 | + mPlayerSeekbar.setProgress((int) time); | ||
| 346 | + | ||
| 347 | + if (time >= 0) { | ||
| 348 | + String progress = millisToString(time, false) + "/" + millisToString(length, false); | ||
| 349 | + mPlayerPosition.setText(progress); | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + Message msg = new Message(); | ||
| 353 | + msg.what = UPDATE_SEEKBAR; | ||
| 354 | + | ||
| 355 | + if (mHandler != null) | ||
| 356 | + mHandler.sendMessageDelayed(msg, 1000); | ||
| 357 | + return (int) time; | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + String millisToString(long millis, boolean text) { | ||
| 361 | + boolean negative = millis < 0; | ||
| 362 | + millis = Math.abs(millis); | ||
| 363 | + | ||
| 364 | + millis /= 1000; | ||
| 365 | + int sec = (int) (millis % 60); | ||
| 366 | + millis /= 60; | ||
| 367 | + int min = (int) (millis % 60); | ||
| 368 | + millis /= 60; | ||
| 369 | + int hours = (int) millis; | ||
| 370 | + | ||
| 371 | + String time; | ||
| 372 | + DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Locale.US); | ||
| 373 | + format.applyPattern("00"); | ||
| 374 | + if (text) { | ||
| 375 | + if (millis > 0) | ||
| 376 | + time = (negative ? "-" : "") + hours + "h" + format.format(min) + "min"; | ||
| 377 | + else if (min > 0) | ||
| 378 | + time = (negative ? "-" : "") + min + "min"; | ||
| 379 | + else | ||
| 380 | + time = (negative ? "-" : "") + sec + "s"; | ||
| 381 | + } else { | ||
| 382 | + if (millis > 0) | ||
| 383 | + time = (negative ? "-" : "") + hours + ":" + format.format(min) + ":" + format.format(sec); | ||
| 384 | + else | ||
| 385 | + time = (negative ? "-" : "") + min + ":" + format.format(sec); | ||
| 386 | + } | ||
| 387 | + return time; | ||
| 388 | + } | ||
| 389 | + | ||
| 390 | + private void videoPlayEnd() { | ||
| 391 | + if (mVideoView != null) { | ||
| 392 | + mVideoView.release(); | ||
| 393 | + mVideoView = null; | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + | ||
| 397 | + mHandler = null; | ||
| 398 | + | ||
| 399 | + finish(); | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + public void onClick(View view) { | ||
| 403 | + mHandler.removeMessages(HIDDEN_SEEKBAR); | ||
| 404 | + Message msg = new Message(); | ||
| 405 | + msg.what = HIDDEN_SEEKBAR; | ||
| 406 | + mHandler.sendMessageDelayed(msg, 3000); | ||
| 407 | + switch (view.getId()) { | ||
| 408 | + case R.id.player_start: | ||
| 409 | + onPlayBtnClick(); | ||
| 410 | + break; | ||
| 411 | + case R.id.back: | ||
| 412 | + videoPlayEnd(); | ||
| 413 | + break; | ||
| 414 | + } | ||
| 415 | + } | ||
| 416 | + | ||
| 417 | + private void onPlayBtnClick() { | ||
| 418 | + mPause = !mPause; | ||
| 419 | + mHandler.removeMessages(HIDDEN_SEEKBAR); | ||
| 420 | + Message msg = new Message(); | ||
| 421 | + msg.what = HIDDEN_SEEKBAR; | ||
| 422 | + mHandler.sendMessageDelayed(msg, 3000); | ||
| 423 | + if (mPause) { | ||
| 424 | + mVideoView.pause(); | ||
| 425 | + } else { | ||
| 426 | + mVideoView.start(); | ||
| 427 | + } | ||
| 428 | + } | ||
| 429 | + | ||
| 430 | + // Maybe we could support gesture detect | ||
| 431 | + private void dealTouchEvent(View view, MotionEvent event) { | ||
| 432 | + mPlayerPanelShow = !mPlayerPanelShow; | ||
| 433 | + | ||
| 434 | + if (mPlayerPanelShow) { | ||
| 435 | + mPlayerPanel.setVisibility(View.VISIBLE); | ||
| 436 | + toppanel.setVisibility(View.VISIBLE); | ||
| 437 | + | ||
| 438 | + Message msg = new Message(); | ||
| 439 | + msg.what = HIDDEN_SEEKBAR; | ||
| 440 | + mHandler.sendMessageDelayed(msg, 3000); | ||
| 441 | + } else { | ||
| 442 | + mPlayerPanel.setVisibility(View.GONE); | ||
| 443 | + toppanel.setVisibility(View.GONE); | ||
| 444 | + mHandler.removeMessages(HIDDEN_SEEKBAR); | ||
| 445 | + } | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/ui/adapter/BitmapCache.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.ui.adapter; | ||
| 2 | + | ||
| 3 | +import android.graphics.Bitmap; | ||
| 4 | +import android.util.LruCache; | ||
| 5 | + | ||
| 6 | +import com.android.volley.toolbox.ImageLoader; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * Created by Lynn on 2017/7/19. | ||
| 10 | + */ | ||
| 11 | + | ||
| 12 | +public class BitmapCache implements ImageLoader.ImageCache { | ||
| 13 | + private LruCache<String, Bitmap> cache; | ||
| 14 | + | ||
| 15 | + public BitmapCache() { | ||
| 16 | + cache = new LruCache<String, Bitmap>(8 * 1024 * 1024) { | ||
| 17 | + @Override | ||
| 18 | + protected int sizeOf(String key, Bitmap bitmap) { | ||
| 19 | + return bitmap.getRowBytes() * bitmap.getHeight(); | ||
| 20 | + } | ||
| 21 | + }; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public Bitmap getBitmap(String url) { | ||
| 26 | + return cache.get(url); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public void putBitmap(String url, Bitmap bitmap) { | ||
| 31 | + cache.put(url, bitmap); | ||
| 32 | + } | ||
| 33 | +} |
app/src/main/java/com/cnlive/demo/shortvideo/ui/adapter/ShortVideoAdapter.java
0 → 100644
| 1 | +package com.cnlive.demo.shortvideo.ui.adapter; | ||
| 2 | + | ||
| 3 | +import android.content.Context; | ||
| 4 | +import android.support.v7.widget.RecyclerView; | ||
| 5 | +import android.view.LayoutInflater; | ||
| 6 | +import android.view.View; | ||
| 7 | +import android.view.ViewGroup; | ||
| 8 | +import android.widget.ImageView; | ||
| 9 | +import android.widget.TextView; | ||
| 10 | + | ||
| 11 | +import com.android.volley.RequestQueue; | ||
| 12 | +import com.android.volley.toolbox.ImageLoader; | ||
| 13 | +import com.android.volley.toolbox.Volley; | ||
| 14 | +import com.cnlive.demo.shortvideo.R; | ||
| 15 | +import com.cnlive.demo.shortvideo.network.model.ShortVideoInfo; | ||
| 16 | + | ||
| 17 | +import java.util.List; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Created by Lynn on 2017/7/19. | ||
| 21 | + */ | ||
| 22 | + | ||
| 23 | +public class ShortVideoAdapter extends RecyclerView.Adapter<ShortVideoAdapter.ViewHolder> implements View.OnClickListener { | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + private List<ShortVideoInfo> shortVideoInfoList; | ||
| 27 | + private OnItemClickListener mOnItemClickListener; | ||
| 28 | + | ||
| 29 | + private Context mContext; | ||
| 30 | + | ||
| 31 | + public ShortVideoAdapter(Context context, List<ShortVideoInfo> list) { | ||
| 32 | + mContext = context; | ||
| 33 | + this.shortVideoInfoList = list; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + @Override | ||
| 37 | + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||
| 38 | + View view = LayoutInflater.from(mContext).inflate(R.layout.short_video_item, parent, false); | ||
| 39 | + ViewHolder viewHolder = new ViewHolder(view); | ||
| 40 | + view.setOnClickListener(this); | ||
| 41 | + return viewHolder; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + @Override | ||
| 45 | + public void onBindViewHolder(ViewHolder holder, int position) { | ||
| 46 | + holder.title.setText(shortVideoInfoList.get(position).getName()); | ||
| 47 | + holder.des.setText(shortVideoInfoList.get(position).getDescription()); | ||
| 48 | + holder.itemView.setTag(position); | ||
| 49 | + RequestQueue requestQueue = Volley.newRequestQueue(mContext); | ||
| 50 | + ImageLoader imageLoader = new ImageLoader(requestQueue, new BitmapCache()); | ||
| 51 | + ImageLoader.ImageListener listener = ImageLoader.getImageListener(holder.coverImg, R.drawable.default_pic, R.drawable.default_pic); | ||
| 52 | + imageLoader.get(shortVideoInfoList.get(position).getPicKey(), listener); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public int getItemCount() { | ||
| 57 | + return shortVideoInfoList.size(); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public void onClick(View view) { | ||
| 62 | + if (mOnItemClickListener != null) { | ||
| 63 | + mOnItemClickListener.onItemClick(view, (int) view.getTag()); | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public void setOnItemClickListener(OnItemClickListener listener) { | ||
| 68 | + this.mOnItemClickListener = listener; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + public static class ViewHolder extends RecyclerView.ViewHolder { | ||
| 72 | + | ||
| 73 | + public TextView title; | ||
| 74 | + public TextView des; | ||
| 75 | + // public TextView time; | ||
| 76 | + public ImageView coverImg; | ||
| 77 | + | ||
| 78 | + public ViewHolder(View itemView) { | ||
| 79 | + super(itemView); | ||
| 80 | + title = (TextView) itemView.findViewById(R.id.video_name); | ||
| 81 | + des = (TextView) itemView.findViewById(R.id.video_description); | ||
| 82 | +// time = (TextView) itemView.findViewById(R.id.video_time); | ||
| 83 | + coverImg = (ImageView) itemView.findViewById(R.id.cover_image); | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + //define interface | ||
| 88 | + public static interface OnItemClickListener { | ||
| 89 | + void onItemClick(View view, int position); | ||
| 90 | + } | ||
| 91 | +} |
app/src/main/res/drawable-xhdpi/default_pic.png
0 → 100644
1.9 KB
app/src/main/res/drawable-xhdpi/player_back.png
0 → 100644
1.06 KB
app/src/main/res/layout/activity_list_video.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:layout_width="match_parent" | ||
| 4 | + android:layout_height="match_parent"> | ||
| 5 | + <android.support.v4.widget.SwipeRefreshLayout | ||
| 6 | + android:id="@+id/contentView" | ||
| 7 | + android:layout_width="match_parent" | ||
| 8 | + android:layout_height="match_parent"> | ||
| 9 | + | ||
| 10 | + <LinearLayout | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="wrap_content" | ||
| 13 | + android:orientation="vertical"> | ||
| 14 | + | ||
| 15 | + <!--<include--> | ||
| 16 | + <!--android:id="@+id/myVideoIncludLayout"--> | ||
| 17 | + <!--layout="@layout/toolbar_my_video" />--> | ||
| 18 | + | ||
| 19 | + <!--<ImageView--> | ||
| 20 | + <!--android:id="@+id/bottom_line"--> | ||
| 21 | + <!--android:layout_width="match_parent"--> | ||
| 22 | + <!--android:layout_height="1px"--> | ||
| 23 | + <!--android:background="#88615F5D"--> | ||
| 24 | + <!--android:contentDescription="@null" />--> | ||
| 25 | + | ||
| 26 | + <android.support.v7.widget.RecyclerView | ||
| 27 | + android:id="@+id/recycler_view" | ||
| 28 | + android:layout_width="match_parent" | ||
| 29 | + android:layout_height="match_parent"/> | ||
| 30 | + | ||
| 31 | + <TextView | ||
| 32 | + android:id="@+id/empty_view" | ||
| 33 | + android:layout_width="match_parent" | ||
| 34 | + android:layout_height="match_parent" | ||
| 35 | + android:layout_gravity="center" | ||
| 36 | + android:gravity="center" | ||
| 37 | + android:text="您还没有录制过视频\n\n快去录制吧⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾*" | ||
| 38 | + android:textSize="20sp" | ||
| 39 | + android:visibility="gone" /> | ||
| 40 | + | ||
| 41 | + </LinearLayout> | ||
| 42 | + </android.support.v4.widget.SwipeRefreshLayout> | ||
| 43 | +</RelativeLayout> |
app/src/main/res/layout/activity_main.xml
| @@ -27,4 +27,11 @@ | @@ -27,4 +27,11 @@ | ||
| 27 | android:layout_marginTop="5dp" | 27 | android:layout_marginTop="5dp" |
| 28 | android:text="导入文件" /> | 28 | android:text="导入文件" /> |
| 29 | 29 | ||
| 30 | + <Button | ||
| 31 | + android:id="@+id/video_list" | ||
| 32 | + android:layout_width="match_parent" | ||
| 33 | + android:layout_height="wrap_content" | ||
| 34 | + android:layout_marginTop="5dp" | ||
| 35 | + android:text="短视频列表" /> | ||
| 36 | + | ||
| 30 | </LinearLayout> | 37 | </LinearLayout> |
app/src/main/res/layout/activity_short_video_play.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | + | ||
| 3 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 4 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 5 | + android:layout_width="match_parent" | ||
| 6 | + android:layout_height="match_parent" | ||
| 7 | + android:background="#000000"> | ||
| 8 | + | ||
| 9 | + <com.cnlive.libs.video.video.VideoView | ||
| 10 | + android:id="@+id/video_view" | ||
| 11 | + android:layout_width="match_parent" | ||
| 12 | + android:layout_height="match_parent" | ||
| 13 | + android:layout_centerInParent="true" /> | ||
| 14 | + | ||
| 15 | + <TextureView | ||
| 16 | + android:id="@+id/player_texture" | ||
| 17 | + android:layout_width="match_parent" | ||
| 18 | + android:layout_height="match_parent" | ||
| 19 | + android:layout_centerInParent="true" | ||
| 20 | + android:visibility="gone" | ||
| 21 | + tools:targetApi="ice_cream_sandwich" /> | ||
| 22 | + | ||
| 23 | + <TextView | ||
| 24 | + android:id="@+id/loading_text" | ||
| 25 | + android:layout_width="wrap_content" | ||
| 26 | + android:layout_height="wrap_content" | ||
| 27 | + android:layout_centerInParent="true" | ||
| 28 | + android:textColor="#FFCC00" /> | ||
| 29 | + | ||
| 30 | + <LinearLayout | ||
| 31 | + android:id="@+id/top_player_panel" | ||
| 32 | + android:layout_width="match_parent" | ||
| 33 | + android:layout_height="48dp" | ||
| 34 | + android:background="@color/transparent2" | ||
| 35 | + android:orientation="horizontal"> | ||
| 36 | + | ||
| 37 | + <ImageView | ||
| 38 | + android:id="@+id/back" | ||
| 39 | + android:layout_width="wrap_content" | ||
| 40 | + android:layout_height="wrap_content" | ||
| 41 | + android:layout_gravity="center_vertical" | ||
| 42 | + android:layout_marginLeft="10dp" | ||
| 43 | + android:onClick="onClick" | ||
| 44 | + android:src="@drawable/player_back" /> | ||
| 45 | + | ||
| 46 | + <TextView | ||
| 47 | + android:id="@+id/video_title" | ||
| 48 | + android:layout_width="wrap_content" | ||
| 49 | + android:layout_height="wrap_content" | ||
| 50 | + android:layout_gravity="center" | ||
| 51 | + android:textColor="@android:color/white" /> | ||
| 52 | + </LinearLayout> | ||
| 53 | + | ||
| 54 | + <LinearLayout | ||
| 55 | + android:layout_width="match_parent" | ||
| 56 | + android:layout_height="wrap_content" | ||
| 57 | + android:layout_alignParentBottom="true" | ||
| 58 | + android:background="@color/transparent2" | ||
| 59 | + android:orientation="vertical"> | ||
| 60 | + | ||
| 61 | + <TextView | ||
| 62 | + android:id="@+id/video_description" | ||
| 63 | + android:layout_width="match_parent" | ||
| 64 | + android:layout_height="wrap_content" | ||
| 65 | + android:layout_alignParentBottom="true" | ||
| 66 | + android:ellipsize="end" | ||
| 67 | + android:padding="10dp" | ||
| 68 | + android:singleLine="true" | ||
| 69 | + android:textColor="@android:color/white" /> | ||
| 70 | + | ||
| 71 | + <LinearLayout | ||
| 72 | + android:id="@+id/player_panel" | ||
| 73 | + android:layout_width="match_parent" | ||
| 74 | + android:layout_height="50dp"> | ||
| 75 | + | ||
| 76 | + <ImageView | ||
| 77 | + android:id="@+id/player_start" | ||
| 78 | + android:layout_width="40dp" | ||
| 79 | + android:layout_height="40dp" | ||
| 80 | + android:layout_marginTop="10dp" | ||
| 81 | + android:background="@drawable/play_state" | ||
| 82 | + android:onClick="onClick" /> | ||
| 83 | + | ||
| 84 | + <RelativeLayout | ||
| 85 | + android:layout_width="match_parent" | ||
| 86 | + android:layout_height="wrap_content" | ||
| 87 | + android:layout_marginTop="10dp"> | ||
| 88 | + | ||
| 89 | + | ||
| 90 | + <TextView | ||
| 91 | + android:id="@+id/player_time" | ||
| 92 | + android:layout_width="wrap_content" | ||
| 93 | + android:layout_height="wrap_content" | ||
| 94 | + android:layout_alignParentLeft="true" | ||
| 95 | + android:text="00:00/00:00" /> | ||
| 96 | + | ||
| 97 | + <SeekBar | ||
| 98 | + android:id="@+id/player_seekbar" | ||
| 99 | + android:layout_width="match_parent" | ||
| 100 | + android:layout_height="wrap_content" | ||
| 101 | + android:layout_below="@+id/player_time" | ||
| 102 | + android:focusable="true" /> | ||
| 103 | + | ||
| 104 | + </RelativeLayout> | ||
| 105 | + | ||
| 106 | + </LinearLayout> | ||
| 107 | + </LinearLayout> | ||
| 108 | +</RelativeLayout> | ||
| 0 | \ No newline at end of file | 109 | \ No newline at end of file |
app/src/main/res/layout/short_video_item.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 3 | + android:orientation="vertical" android:layout_width="match_parent" | ||
| 4 | + android:layout_height="wrap_content"> | ||
| 5 | + | ||
| 6 | + <LinearLayout | ||
| 7 | + android:layout_width="match_parent" | ||
| 8 | + android:layout_height="wrap_content" | ||
| 9 | + android:orientation="horizontal"> | ||
| 10 | + | ||
| 11 | + <ImageView | ||
| 12 | + android:id="@+id/cover_image" | ||
| 13 | + android:layout_width="90dp" | ||
| 14 | + android:layout_height="90dp" | ||
| 15 | + android:padding="2dp" /> | ||
| 16 | + | ||
| 17 | + <LinearLayout | ||
| 18 | + android:layout_width="match_parent" | ||
| 19 | + android:layout_height="90dp" | ||
| 20 | + android:layout_marginLeft="10dp" | ||
| 21 | + android:gravity="center_vertical" | ||
| 22 | + android:orientation="vertical"> | ||
| 23 | + | ||
| 24 | + <TextView | ||
| 25 | + android:id="@+id/video_name" | ||
| 26 | + android:layout_width="wrap_content" | ||
| 27 | + android:layout_height="wrap_content" | ||
| 28 | + android:textColor="@android:color/black" | ||
| 29 | + android:textSize="18sp" /> | ||
| 30 | + | ||
| 31 | + <!--<TextView--> | ||
| 32 | + <!--android:id="@+id/video_time"--> | ||
| 33 | + <!--android:layout_width="wrap_content"--> | ||
| 34 | + <!--android:layout_height="wrap_content"--> | ||
| 35 | + <!--android:layout_marginLeft="10dp"--> | ||
| 36 | + <!--android:layout_marginTop="10dp"--> | ||
| 37 | + <!--android:text="@{shortVideoInfo.createTime}"--> | ||
| 38 | + <!--android:textSize="14sp" />--> | ||
| 39 | + | ||
| 40 | + <TextView | ||
| 41 | + android:id="@+id/video_description" | ||
| 42 | + android:layout_width="wrap_content" | ||
| 43 | + android:layout_height="wrap_content" | ||
| 44 | + android:layout_marginLeft="10dp" | ||
| 45 | + android:layout_marginTop="3dp" | ||
| 46 | + android:textSize="14sp" /> | ||
| 47 | + | ||
| 48 | + </LinearLayout> | ||
| 49 | + | ||
| 50 | + </LinearLayout> | ||
| 51 | + | ||
| 52 | + <View | ||
| 53 | + android:layout_width="match_parent" | ||
| 54 | + android:layout_height="1dp" | ||
| 55 | + android:background="#dcdcdc" /> | ||
| 56 | + | ||
| 57 | +</LinearLayout> | ||
| 0 | \ No newline at end of file | 58 | \ No newline at end of file |
app/src/main/res/layout/toolbar_my_video.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<layout> | ||
| 3 | + | ||
| 4 | + <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 5 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| 6 | + android:id="@+id/myVideoToolBar" | ||
| 7 | + android:layout_width="match_parent" | ||
| 8 | + android:layout_height="?attr/actionBarSize" | ||
| 9 | + android:focusable="true" | ||
| 10 | + android:focusableInTouchMode="true" | ||
| 11 | + app:popupTheme="@style/ThemeOverlay.AppCompat.Light"> | ||
| 12 | + | ||
| 13 | + <ImageView | ||
| 14 | + android:id="@+id/title_back" | ||
| 15 | + android:layout_width="wrap_content" | ||
| 16 | + android:layout_height="match_parent" | ||
| 17 | + android:visibility="visible" | ||
| 18 | + android:src="@drawable/back"/> | ||
| 19 | + | ||
| 20 | + <TextView | ||
| 21 | + android:id="@+id/title_name" | ||
| 22 | + android:layout_width="wrap_content" | ||
| 23 | + android:layout_height="wrap_content" | ||
| 24 | + android:layout_gravity="center_horizontal" | ||
| 25 | + android:singleLine="true" | ||
| 26 | + android:text="there is a title" | ||
| 27 | + android:textColor="@android:color/black" | ||
| 28 | + android:textSize="20sp" | ||
| 29 | + android:onClick="onClick"/> | ||
| 30 | + | ||
| 31 | + </android.support.v7.widget.Toolbar> | ||
| 32 | + | ||
| 33 | +</layout> | ||
| 0 | \ No newline at end of file | 34 | \ No newline at end of file |
doc/短视频SDK说明文档.pdf
No preview for this file type