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 | 20 | <uses-permission android:name="android.permission.VIBRATE" /> |
| 21 | 21 | |
| 22 | 22 | <application |
| 23 | - android:name="com.cnlive.demo.shortvideo.application.CNShrotVideoApplication" | |
| 23 | + android:name=".application.CNShrotVideoApplication" | |
| 24 | 24 | android:allowBackup="true" |
| 25 | 25 | android:icon="@mipmap/ic_launcher" |
| 26 | 26 | android:label="@string/app_name" |
| 27 | 27 | android:roundIcon="@mipmap/ic_launcher_round" |
| 28 | 28 | android:supportsRtl="true" |
| 29 | 29 | android:theme="@style/AppTheme"> |
| 30 | - <activity android:name="com.cnlive.demo.shortvideo.ui.activity.MainActivity"> | |
| 30 | + <activity android:name=".ui.activity.MainActivity"> | |
| 31 | 31 | <intent-filter> |
| 32 | 32 | <action android:name="android.intent.action.MAIN" /> |
| 33 | 33 | |
| ... | ... | @@ -35,18 +35,20 @@ |
| 35 | 35 | </intent-filter> |
| 36 | 36 | </activity> |
| 37 | 37 | <activity |
| 38 | - android:name="com.cnlive.demo.shortvideo.ui.activity.RecordActivity" | |
| 38 | + android:name=".ui.activity.RecordActivity" | |
| 39 | 39 | android:configChanges="orientation|keyboardHidden|screenSize" |
| 40 | 40 | android:launchMode="singleTop" |
| 41 | 41 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
| 42 | 42 | <activity |
| 43 | - android:name="com.cnlive.demo.shortvideo.ui.activity.EditActivity" | |
| 43 | + android:name=".ui.activity.EditActivity" | |
| 44 | 44 | android:configChanges="orientation|keyboardHidden|screenSize" |
| 45 | 45 | android:launchMode="singleTop" |
| 46 | 46 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
| 47 | 47 | <activity |
| 48 | - android:name="com.cnlive.demo.shortvideo.ui.activity.FileImportActivity" | |
| 48 | + android:name=".ui.activity.FileImportActivity" | |
| 49 | 49 | android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> |
| 50 | + <activity android:name=".ui.activity.ListVideoActivity"></activity> | |
| 51 | + <activity android:name=".ui.activity.ShortVideoPlayActivity"/> | |
| 50 | 52 | </application> |
| 51 | 53 | |
| 52 | 54 | </manifest> |
| 53 | 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 | 5 | import android.content.Intent; |
| 6 | 6 | import android.database.Cursor; |
| 7 | 7 | import android.database.DatabaseUtils; |
| 8 | +import android.graphics.Bitmap; | |
| 8 | 9 | import android.net.Uri; |
| 9 | 10 | import android.os.Build; |
| 10 | 11 | import android.os.Environment; |
| ... | ... | @@ -14,6 +15,9 @@ import android.util.Log; |
| 14 | 15 | import android.webkit.MimeTypeMap; |
| 15 | 16 | |
| 16 | 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 | 23 | * Created by Lynn on 6/28/2017. |
| ... | ... | @@ -289,4 +293,53 @@ public class FileUtils { |
| 289 | 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 | 49 | import android.widget.Toast; |
| 50 | 50 | |
| 51 | 51 | import com.cnlive.demo.shortvideo.R; |
| 52 | +import com.cnlive.demo.shortvideo.file.FileUtils; | |
| 52 | 53 | import com.cnlive.demo.shortvideo.ui.dialog.ShortVideoConfigDialog; |
| 53 | 54 | import com.cnlive.demo.shortvideo.sticker.StickerAdapter; |
| 54 | 55 | import com.cnlive.demo.shortvideo.util.ColorPicker; |
| ... | ... | @@ -938,7 +939,7 @@ public class EditActivity extends AppCompatActivity implements ActivityCompat.On |
| 938 | 939 | mComposeAlertDialog.composeFinished(strings[0]); |
| 939 | 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 | 944 | case ShortVideoConstants.SHORTVIDEO_COMPOSE_ABORTED: |
| 944 | 945 | break; |
| ... | ... | @@ -1695,7 +1696,7 @@ public class EditActivity extends AppCompatActivity implements ActivityCompat.On |
| 1695 | 1696 | } catch (Exception e) { |
| 1696 | 1697 | e.printStackTrace(); |
| 1697 | 1698 | } |
| 1698 | - }else { | |
| 1699 | + } else { | |
| 1699 | 1700 | mMediaPlayer.setDataSource(new IDataSource() { |
| 1700 | 1701 | @Override |
| 1701 | 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 | 1 | package com.cnlive.demo.shortvideo.ui.activity; |
| 2 | 2 | |
| 3 | 3 | import android.content.DialogInterface; |
| 4 | +import android.content.Intent; | |
| 4 | 5 | import android.os.Handler; |
| 5 | 6 | import android.support.v7.app.AppCompatActivity; |
| 6 | 7 | import android.os.Bundle; |
| ... | ... | @@ -21,6 +22,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe |
| 21 | 22 | private Button mAuthButton; |
| 22 | 23 | private Button mRecordButton; |
| 23 | 24 | private Button mImportFileButton; |
| 25 | + private Button mVideoListButton; | |
| 24 | 26 | |
| 25 | 27 | private Handler mMainHandler; |
| 26 | 28 | |
| ... | ... | @@ -40,6 +42,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe |
| 40 | 42 | mRecordButton.setOnClickListener(this); |
| 41 | 43 | mImportFileButton = (Button) findViewById(R.id.import_file); |
| 42 | 44 | mImportFileButton.setOnClickListener(this); |
| 45 | + mVideoListButton = (Button) findViewById(R.id.video_list); | |
| 46 | + mVideoListButton.setOnClickListener(this); | |
| 43 | 47 | } |
| 44 | 48 | |
| 45 | 49 | @Override |
| ... | ... | @@ -65,6 +69,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe |
| 65 | 69 | case R.id.import_file: |
| 66 | 70 | onImportFileClick(); |
| 67 | 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 | 146 | private void onImportFileClick() { |
| 140 | 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 | 27 | android:layout_marginTop="5dp" |
| 28 | 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 | 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 | 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 | 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 | 34 | \ No newline at end of file | ... | ... |
doc/短视频SDK说明文档.pdf
No preview for this file type