├── .gitattributes ├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── shirlman │ │ └── yiplayer │ │ ├── MyApplication.java │ │ ├── core │ │ └── OnlineQueryService.java │ │ ├── events │ │ ├── DictionaryEvent.java │ │ └── VideoEvents.java │ │ ├── jobs │ │ ├── GetLocalVideoListJob.java │ │ └── JobPriority.java │ │ ├── models │ │ ├── ICibaResponse.java │ │ ├── ShooterSubtitleDetailResponse.java │ │ ├── ShooterSubtitleResponse.java │ │ ├── VideoGroup.java │ │ ├── VideoInfo.java │ │ └── YoudaoResponse.java │ │ ├── ui │ │ ├── activities │ │ │ ├── MainActivity.java │ │ │ └── VideoActivity.java │ │ ├── adapters │ │ │ ├── LocalVideoAdapter.java │ │ │ ├── LocalVideoGroupAdapter.java │ │ │ └── OnlineSubtitleAdapter.java │ │ ├── fragments │ │ │ ├── LocalVideoFragment.java │ │ │ └── LocalVideoGroupFragment.java │ │ └── widgets │ │ │ └── VideoController.java │ │ └── util │ │ ├── FileUtils.java │ │ └── StringUtils.java │ └── res │ ├── drawable-v21 │ ├── ic_menu_camera.xml │ ├── ic_menu_gallery.xml │ ├── ic_menu_manage.xml │ ├── ic_menu_send.xml │ ├── ic_menu_share.xml │ ├── ic_menu_slideshow.xml │ ├── video_controller_lock.png │ ├── video_controller_next.png │ ├── video_controller_pause.png │ ├── video_controller_play.png │ └── video_controller_settings.png │ ├── drawable │ ├── local_video_info_bg.xml │ ├── seek_bar_background_fill.xml │ ├── seek_bar_bg.xml │ ├── seek_bar_progress_fill.xml │ ├── side_nav_bar.xml │ ├── video_controller_bg.xml │ └── video_lock_bg.xml │ ├── layout │ ├── activity_main.xml │ ├── app_bar_main.xml │ ├── content_main.xml │ ├── local_video_fragment.xml │ ├── local_video_item.xml │ ├── nav_header_main.xml │ ├── online_subtitle.xml │ ├── online_subtitle_item.xml │ ├── video_controller.xml │ └── video_view.xml │ ├── menu │ ├── activity_main_drawer.xml │ └── main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── drawables.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── com.shirlman.yiplayer_main_activity.png ├── com.shirlman.yiplayer_video_controller.png └── 微信图片_20170522195813.png ├── settings.gradle └── vlc ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── java └── org │ └── videolan │ └── libvlc │ ├── AWindow.java │ ├── AWindowNativeHandler.java │ ├── Dialog.java │ ├── IVLCVout.java │ ├── LibVLC.java │ ├── Media.java │ ├── MediaDiscoverer.java │ ├── MediaList.java │ ├── MediaPlayer.java │ ├── VLCEvent.java │ ├── VLCObject.java │ ├── media │ ├── MediaPlayer.java │ └── VideoView.java │ ├── subtitle │ ├── Caption.java │ ├── FatalParsingException.java │ ├── FormatASS.java │ ├── FormatSCC.java │ ├── FormatSRT.java │ ├── FormatSTL.java │ ├── FormatTTML.java │ ├── Region.java │ ├── Style.java │ ├── SubtitleFormat.java │ ├── Time.java │ ├── TimedTextFileFormat.java │ ├── TimedTextObject.java │ └── TimedTextProcessor.java │ └── util │ ├── AndroidUtil.java │ ├── Dumper.java │ ├── Extensions.java │ ├── HWDecoderUtil.java │ ├── MediaBrowser.java │ └── VLCUtil.java ├── jniLibs └── armeabi-v7a │ ├── libanw.10.so │ ├── libanw.13.so │ ├── libanw.14.so │ ├── libanw.18.so │ ├── libanw.21.so │ ├── libcompat.7.so │ ├── libiomx.10.so │ ├── libiomx.13.so │ ├── libiomx.14.so │ ├── libvlc.so │ └── libvlcjni.so └── res └── values └── strings.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | YiPlayer -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YiPlayer 2 | A video player which can help users to learn English through videos. 3 | > **Current Feature:** 4 | 5 | > - Play local videos 6 | > - Basic video control, like play, pause, resume, lock 7 | > - Support local subtitle 8 | > - Implement setOnTimedTextListener 9 | > - Query word from iCiba 10 | > - Query subtitle from shooter.cn 11 | 12 | If you want to use VideoView library(Based on VLC Android SDK 2.0.2), you can copy the VLC library to your project, it's totally independent. 13 | 14 | ![YiPlayer Screenshot1](https://github.com/Shirlman/YiPlayer/blob/master/images/com.shirlman.yiplayer_video_controller.png) 15 | ![YiPlayer Screenshot2](https://github.com/Shirlman/YiPlayer/blob/master/images/com.shirlman.yiplayer_main_activity.png) 16 | ![YiPlayer Screenshot3](https://github.com/Shirlman/YiPlayer/blob/master/images/微信图片_20170522195813.png) 17 | ------ | ----- | ----- 18 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.0" 6 | 7 | defaultConfig { 8 | applicationId "com.shirlman.yiplayer" 9 | minSdkVersion 15 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:24.0.0' 25 | compile 'com.android.support:design:24.0.0' 26 | compile 'com.squareup.retrofit2:retrofit:2.1.0' 27 | compile 'com.squareup.retrofit2:converter-gson:2.1.0' 28 | compile ('com.squareup.retrofit2:converter-simplexml:2.1.0') { 29 | // if not exclude will cause build error 30 | exclude module: 'stax-api' 31 | exclude module: 'stax' 32 | exclude module: 'xpp3' 33 | } 34 | compile 'com.birbit:android-priority-jobqueue:2.0.0-alpha5' 35 | compile 'org.greenrobot:eventbus:3.0.0' 36 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' 37 | compile 'com.android.support:recyclerview-v7:24.0.0' 38 | compile project(path: ':vlc') 39 | } 40 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer; 2 | 3 | import android.app.Application; 4 | 5 | import com.birbit.android.jobqueue.JobManager; 6 | import com.birbit.android.jobqueue.config.Configuration; 7 | import com.nostra13.universalimageloader.core.DisplayImageOptions; 8 | import com.nostra13.universalimageloader.core.ImageLoader; 9 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 10 | 11 | /** 12 | * Created by KB-Server on 2016/6/24. 13 | */ 14 | public class MyApplication extends Application { 15 | private static MyApplication mMyApplication; 16 | private static JobManager mJobManager; 17 | 18 | @Override 19 | public void onCreate() { 20 | super.onCreate(); 21 | mMyApplication = this; 22 | 23 | initImageLoader(); 24 | } 25 | 26 | public static MyApplication getInstance() { 27 | return mMyApplication; 28 | } 29 | 30 | public static JobManager getJobManager() { 31 | if(mJobManager == null) { 32 | Configuration jobConfiguration = new Configuration.Builder(mMyApplication.getApplicationContext()) 33 | .minConsumerCount(5)//always keep at least one consumer alive 34 | .maxConsumerCount(10)//up to 5 consumers at a time 35 | .loadFactor(5)//5 jobs per consumer 36 | //.consumerKeepAlive(120)//wait 2 minute 37 | .build(); 38 | 39 | mJobManager = new JobManager(jobConfiguration); 40 | } 41 | 42 | return mJobManager; 43 | } 44 | 45 | private void initImageLoader() { 46 | DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() 47 | // .cacheInMemory(true) 48 | // .cacheOnDisk(true) 49 | .build(); 50 | 51 | ImageLoaderConfiguration imageLoaderConfiguration = 52 | new ImageLoaderConfiguration.Builder(getApplicationContext()) 53 | .defaultDisplayImageOptions(defaultOptions) 54 | .build(); 55 | 56 | ImageLoader.getInstance().init(imageLoaderConfiguration); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/core/OnlineQueryService.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.core; 2 | 3 | import com.shirlman.yiplayer.models.ICibaResponse; 4 | import com.shirlman.yiplayer.models.ShooterSubtitleDetailResponse; 5 | import com.shirlman.yiplayer.models.ShooterSubtitleResponse; 6 | import com.shirlman.yiplayer.models.YoudaoResponse; 7 | 8 | import java.util.Map; 9 | 10 | import retrofit2.Call; 11 | import retrofit2.http.Body; 12 | import retrofit2.http.GET; 13 | import retrofit2.http.Headers; 14 | import retrofit2.http.Path; 15 | import retrofit2.http.Query; 16 | import retrofit2.http.QueryMap; 17 | 18 | /** 19 | * Created by KB-Server on 2016/7/24. 20 | */ 21 | public interface OnlineQueryService { 22 | @GET("http://fanyi.youdao.com/openapi.do") 23 | Call queryWordFromYoudao(@QueryMap Map filters); 24 | 25 | @GET("http://dict-co.iciba.com/api/dictionary.php") 26 | Call queryWordFromICiba(@QueryMap Map filters); 27 | 28 | @GET("http://api.assrt.net/v1/sub/search") 29 | Call querySubtitleFromShooter(@QueryMap Map filters); 30 | 31 | @GET("http://api.assrt.net/v1/sub/detail") 32 | Call getSubtitleDetailFromShooter(@QueryMap Map filters); 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/events/DictionaryEvent.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.events; 2 | 3 | /** 4 | * Created by KB-Server on 2016/7/24. 5 | */ 6 | public class DictionaryEvent { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/events/VideoEvents.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.events; 2 | 3 | import com.shirlman.yiplayer.models.VideoGroup; 4 | import com.shirlman.yiplayer.models.VideoInfo; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by KB-Server on 2016/6/24. 10 | */ 11 | public class VideoEvents { 12 | public static class OnLocalVideoListGot { 13 | private List videoGroupList; 14 | 15 | public OnLocalVideoListGot(List videoGroupList) { 16 | this.videoGroupList = videoGroupList; 17 | } 18 | 19 | public List getVideoGroupList() { 20 | return videoGroupList; 21 | } 22 | } 23 | 24 | public static class OpenVideoGroup { 25 | private VideoGroup videoGroup; 26 | 27 | public OpenVideoGroup(VideoGroup videoGroup) { 28 | this.videoGroup = videoGroup; 29 | } 30 | 31 | public VideoGroup getVideoGroup() { 32 | return videoGroup; 33 | } 34 | } 35 | 36 | public static class PlayLocalVideo { 37 | private VideoInfo videoInfo; 38 | 39 | public PlayLocalVideo(VideoInfo videoInfo) { 40 | this.videoInfo = videoInfo; 41 | } 42 | 43 | public VideoInfo getVideoInfo() { 44 | return videoInfo; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/jobs/GetLocalVideoListJob.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.jobs; 2 | 3 | import android.database.Cursor; 4 | import android.provider.MediaStore; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | 8 | import com.birbit.android.jobqueue.Job; 9 | import com.birbit.android.jobqueue.Params; 10 | import com.birbit.android.jobqueue.RetryConstraint; 11 | import com.shirlman.yiplayer.MyApplication; 12 | import com.shirlman.yiplayer.events.VideoEvents; 13 | import com.shirlman.yiplayer.models.VideoGroup; 14 | import com.shirlman.yiplayer.models.VideoInfo; 15 | 16 | import org.greenrobot.eventbus.EventBus; 17 | 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.List; 21 | 22 | /** 23 | * Created by KB-Server on 2016/6/24. 24 | */ 25 | public class GetLocalVideoListJob extends Job { 26 | public GetLocalVideoListJob() { 27 | super(new Params(JobPriority.HIGH).requireNetwork()); 28 | } 29 | 30 | @Override 31 | public void onAdded() { 32 | 33 | } 34 | 35 | @Override 36 | public void onRun() throws Throwable { 37 | HashMap videoGroupHashMap = new HashMap<>(); 38 | 39 | String[] thumbColumns = { 40 | MediaStore.Video.Thumbnails.DATA, 41 | MediaStore.Video.Thumbnails.VIDEO_ID 42 | }; 43 | 44 | String[] mediaColumns = { 45 | MediaStore.Video.Media._ID, 46 | MediaStore.Video.Media.DATA, 47 | MediaStore.Video.Media.TITLE, 48 | MediaStore.Video.Media.MIME_TYPE, 49 | MediaStore.Video.Media.DISPLAY_NAME, 50 | MediaStore.Video.Media.DURATION, 51 | MediaStore.Video.Media.SIZE, 52 | }; 53 | 54 | Cursor cursor = MyApplication.getInstance().getContentResolver().query( 55 | MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaColumns, null, null, null); 56 | 57 | if (cursor != null && cursor.moveToFirst()) { 58 | do { 59 | VideoInfo videoInfo = new VideoInfo(); 60 | 61 | int mediaId = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media._ID)); 62 | 63 | Cursor thumbCursor = MyApplication.getInstance().getContentResolver().query( 64 | MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, thumbColumns, 65 | MediaStore.Video.Thumbnails.VIDEO_ID+ "=" + mediaId, 66 | null, 67 | null); 68 | 69 | if (thumbCursor != null && thumbCursor.moveToFirst()) { 70 | videoInfo.setThumbPath(thumbCursor.getString(thumbCursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA))); 71 | } 72 | 73 | videoInfo.setTitle(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE))); 74 | videoInfo.setDisplayName(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME))); 75 | 76 | int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)); 77 | videoInfo.setDuration(duration); 78 | 79 | videoInfo.setSize(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE))); 80 | 81 | String videoPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); 82 | videoInfo.setPath(videoPath); 83 | 84 | String videoFolderPath = videoPath.substring(0, videoPath.lastIndexOf("/")); 85 | videoInfo.setFolderPath(videoFolderPath); 86 | 87 | String videoGroupName = videoFolderPath.substring(videoFolderPath.lastIndexOf("/") + 1); 88 | 89 | if(!videoGroupHashMap.containsKey(videoGroupName)) { 90 | VideoGroup videoGroup = new VideoGroup(); 91 | videoGroup.setGroupName(videoGroupName); 92 | 93 | List videoInfoList = new ArrayList<>(); 94 | videoInfoList.add(videoInfo); 95 | videoGroup.setVideoInfoList(videoInfoList); 96 | 97 | videoGroupHashMap.put(videoGroupName, videoGroup); 98 | } else { 99 | videoGroupHashMap.get(videoGroupName).getVideoInfoList().add(videoInfo); 100 | } 101 | } while (cursor.moveToNext()); 102 | } 103 | 104 | EventBus.getDefault().post(new VideoEvents.OnLocalVideoListGot(new ArrayList<>(videoGroupHashMap.values()))); 105 | } 106 | 107 | @Override 108 | protected void onCancel(int cancelReason, @Nullable Throwable throwable) { 109 | 110 | } 111 | 112 | @Override 113 | protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { 114 | return null; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/jobs/JobPriority.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.jobs; 2 | 3 | /** 4 | * Created by KB-Server on 2016/6/24. 5 | */ 6 | public class JobPriority { 7 | public static int LOW = 0; 8 | public static int MID = 500; 9 | public static int HIGH = 1000; 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/models/ICibaResponse.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.models; 2 | 3 | import org.simpleframework.xml.Attribute; 4 | import org.simpleframework.xml.Element; 5 | import org.simpleframework.xml.ElementList; 6 | import org.simpleframework.xml.Root; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by KB-Server on 2016/7/24. 12 | */ 13 | @Root(name = "dict", strict = false) 14 | public class ICibaResponse { 15 | @Attribute(name = "num", required = false) 16 | private String num; 17 | @Attribute(name = "id", required = false) 18 | private String id; 19 | @Attribute(name = "name", required = false) 20 | private String name; 21 | @Element(name = "key") 22 | private String key; 23 | @ElementList(inline = true, entry="ps", required = false) 24 | private List ps; 25 | @ElementList(inline = true, entry="pron", required = false) 26 | private List pron; 27 | @ElementList(inline = true, entry="pos", required = false) 28 | private List pos; 29 | @ElementList(inline = true, entry="acceptation", required = false) 30 | private List acceptation; 31 | /** 32 | * orig : In ` I wish you were here', ` were'is in the subjunctive. 33 | * trans : 在Iwishyou were here一 句中, were 表达的是虚拟语气. 34 | */ 35 | @ElementList(inline = true, entry="sent") 36 | private List sent; 37 | 38 | public String getNum() { 39 | return num; 40 | } 41 | 42 | public void setNum(String num) { 43 | this.num = num; 44 | } 45 | 46 | public String getId() { 47 | return id; 48 | } 49 | 50 | public void setId(String id) { 51 | this.id = id; 52 | } 53 | 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | public void setName(String name) { 59 | this.name = name; 60 | } 61 | 62 | public String getKey() { 63 | return key; 64 | } 65 | 66 | public void setKey(String key) { 67 | this.key = key; 68 | } 69 | 70 | public List getPs() { 71 | return ps; 72 | } 73 | 74 | public void setPs(List ps) { 75 | this.ps = ps; 76 | } 77 | 78 | public List getPron() { 79 | return pron; 80 | } 81 | 82 | public void setPron(List pron) { 83 | this.pron = pron; 84 | } 85 | 86 | public List getPos() { 87 | return pos; 88 | } 89 | 90 | public void setPos(List pos) { 91 | this.pos = pos; 92 | } 93 | 94 | public List getAcceptation() { 95 | return acceptation; 96 | } 97 | 98 | public void setAcceptation(List acceptation) { 99 | this.acceptation = acceptation; 100 | } 101 | 102 | public List getSent() { 103 | return sent; 104 | } 105 | 106 | public void setSent(List sent) { 107 | this.sent = sent; 108 | } 109 | 110 | @Element(name = "sent") 111 | public static class SentBean { 112 | @Element(name = "orig") 113 | private String orig; 114 | @Element(name = "trans") 115 | private String trans; 116 | 117 | public String getOrig() { 118 | return orig; 119 | } 120 | 121 | public void setOrig(String orig) { 122 | this.orig = orig; 123 | } 124 | 125 | public String getTrans() { 126 | return trans; 127 | } 128 | 129 | public void setTrans(String trans) { 130 | this.trans = trans; 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/models/VideoGroup.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.models; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by KB-Server on 2016/6/25. 8 | */ 9 | public class VideoGroup implements Serializable { 10 | private List videoInfoList; 11 | private String groupName; 12 | 13 | public List getVideoInfoList() { 14 | return videoInfoList; 15 | } 16 | 17 | public void setVideoInfoList(List videoInfoList) { 18 | this.videoInfoList = videoInfoList; 19 | } 20 | 21 | public String getGroupName() { 22 | return groupName; 23 | } 24 | 25 | public void setGroupName(String groupName) { 26 | this.groupName = groupName; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/models/VideoInfo.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.models; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by KB-Server on 2016/6/23. 7 | */ 8 | public class VideoInfo implements Serializable { 9 | private String title; 10 | private String path; 11 | private long size; 12 | private String thumbPath; 13 | private int duration; 14 | private String folderPath; 15 | private String displayName; 16 | 17 | public String getTitle() { 18 | return title; 19 | } 20 | 21 | public void setTitle(String title) { 22 | this.title = title; 23 | } 24 | 25 | public String getPath() { 26 | return path; 27 | } 28 | 29 | public void setPath(String path) { 30 | this.path = path; 31 | } 32 | 33 | public long getSize() { 34 | return size; 35 | } 36 | 37 | public void setSize(long size) { 38 | this.size = size; 39 | } 40 | 41 | public String getThumbPath() { 42 | return thumbPath; 43 | } 44 | 45 | public void setThumbPath(String thumbPath) { 46 | this.thumbPath = thumbPath; 47 | } 48 | 49 | public int getDuration() { 50 | return duration; 51 | } 52 | 53 | public void setDuration(int duration) { 54 | this.duration = duration; 55 | } 56 | 57 | public String getFolderPath() { 58 | return folderPath; 59 | } 60 | 61 | public void setFolderPath(String folderPath) { 62 | this.folderPath = folderPath; 63 | } 64 | 65 | public String getDisplayName() { 66 | return displayName; 67 | } 68 | 69 | public void setDisplayName(String displayName) { 70 | this.displayName = displayName; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/models/YoudaoResponse.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.models; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by KB-Server on 2016/7/24. 9 | */ 10 | public class YoudaoResponse { 11 | 12 | /** 13 | * us-phonetic : 'pɝsənl 14 | * phonetic : 'pɜːs(ə)n(ə)l 15 | * uk-phonetic : 'pɜːs(ə)n(ə)l 16 | * explains : ["n. 人事消息栏;人称代名词","adj. 个人的;身体的;亲自的"] 17 | */ 18 | 19 | private BasicBean basic; 20 | /** 21 | * translation : ["个人"] 22 | * basic : {"us-phonetic":"'pɝsənl","phonetic":"'pɜːs(ə)n(ə)l","uk-phonetic":"'pɜːs(ə)n(ə)l","explains":["n. 人事消息栏;人称代名词","adj. 个人的;身体的;亲自的"]} 23 | * query : personal 24 | * errorCode : 0 25 | * web : [{"value":["个人的","私人的","人身"],"key":"personal"},{"value":["个人所得","个人收入","个人所得"],"key":"Personal income"},{"value":["个人电脑","个人计算机","人计算机"],"key":"personal computer"}] 26 | */ 27 | 28 | private String query; 29 | private int errorCode; 30 | private List translation; 31 | /** 32 | * value : ["个人的","私人的","人身"] 33 | * key : personal 34 | */ 35 | 36 | private List web; 37 | 38 | public BasicBean getBasic() { 39 | return basic; 40 | } 41 | 42 | public void setBasic(BasicBean basic) { 43 | this.basic = basic; 44 | } 45 | 46 | public String getQuery() { 47 | return query; 48 | } 49 | 50 | public void setQuery(String query) { 51 | this.query = query; 52 | } 53 | 54 | public int getErrorCode() { 55 | return errorCode; 56 | } 57 | 58 | public void setErrorCode(int errorCode) { 59 | this.errorCode = errorCode; 60 | } 61 | 62 | public List getTranslation() { 63 | return translation; 64 | } 65 | 66 | public void setTranslation(List translation) { 67 | this.translation = translation; 68 | } 69 | 70 | public List getWeb() { 71 | return web; 72 | } 73 | 74 | public void setWeb(List web) { 75 | this.web = web; 76 | } 77 | 78 | public static class BasicBean { 79 | private List explains; 80 | @SerializedName("us-phonetic") 81 | private String us_phonetic; 82 | private String phonetic; 83 | @SerializedName("uk-phonetic") 84 | private String uk_phonetic; 85 | 86 | public List getExplains() { 87 | return explains; 88 | } 89 | 90 | public void setExplains(List explains) { 91 | this.explains = explains; 92 | } 93 | 94 | public String getUs_phonetic() { 95 | return us_phonetic; 96 | } 97 | 98 | public void setUs_phonetic(String us_phonetic) { 99 | this.us_phonetic = us_phonetic; 100 | } 101 | 102 | public String getPhonetic() { 103 | return phonetic; 104 | } 105 | 106 | public void setPhonetic(String phonetic) { 107 | this.phonetic = phonetic; 108 | } 109 | 110 | public String getUk_phonetic() { 111 | return uk_phonetic; 112 | } 113 | 114 | public void setUk_phonetic(String uk_phonetic) { 115 | this.uk_phonetic = uk_phonetic; 116 | } 117 | } 118 | 119 | public static class WebBean { 120 | private String key; 121 | private List value; 122 | 123 | public String getKey() { 124 | return key; 125 | } 126 | 127 | public void setKey(String key) { 128 | this.key = key; 129 | } 130 | 131 | public List getValue() { 132 | return value; 133 | } 134 | 135 | public void setValue(List value) { 136 | this.value = value; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/activities/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentTransaction; 7 | import android.support.design.widget.NavigationView; 8 | import android.support.v4.view.GravityCompat; 9 | import android.support.v4.widget.DrawerLayout; 10 | import android.support.v7.app.ActionBarDrawerToggle; 11 | import android.support.v7.app.AppCompatActivity; 12 | import android.support.v7.widget.Toolbar; 13 | import android.view.Menu; 14 | import android.view.MenuItem; 15 | 16 | import com.shirlman.yiplayer.R; 17 | import com.shirlman.yiplayer.events.VideoEvents; 18 | import com.shirlman.yiplayer.models.VideoGroup; 19 | import com.shirlman.yiplayer.models.VideoInfo; 20 | import com.shirlman.yiplayer.ui.fragments.LocalVideoFragment; 21 | import com.shirlman.yiplayer.ui.fragments.LocalVideoGroupFragment; 22 | 23 | import org.greenrobot.eventbus.EventBus; 24 | import org.greenrobot.eventbus.Subscribe; 25 | import org.greenrobot.eventbus.ThreadMode; 26 | 27 | import java.util.List; 28 | 29 | public class MainActivity extends AppCompatActivity 30 | implements NavigationView.OnNavigationItemSelectedListener { 31 | 32 | private final String TAG = MainActivity.class.getSimpleName(); 33 | 34 | @Override 35 | protected void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | 38 | EventBus.getDefault().register(this); 39 | 40 | setContentView(R.layout.activity_main); 41 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 42 | setSupportActionBar(toolbar); 43 | 44 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 45 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( 46 | this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 47 | drawer.setDrawerListener(toggle); 48 | toggle.syncState(); 49 | 50 | NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); 51 | navigationView.setNavigationItemSelectedListener(this); 52 | 53 | getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new LocalVideoGroupFragment()).commit(); 54 | } 55 | 56 | @Override 57 | public void onBackPressed() { 58 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 59 | if (drawer.isDrawerOpen(GravityCompat.START)) { 60 | drawer.closeDrawer(GravityCompat.START); 61 | } else { 62 | super.onBackPressed(); 63 | } 64 | } 65 | 66 | @Override 67 | public boolean onCreateOptionsMenu(Menu menu) { 68 | // Inflate the menu; this adds items to the action bar if it is present. 69 | getMenuInflater().inflate(R.menu.main, menu); 70 | return true; 71 | } 72 | 73 | @Override 74 | public boolean onOptionsItemSelected(MenuItem item) { 75 | // Handle action bar item clicks here. The action bar will 76 | // automatically handle clicks on the Home/Up button, so long 77 | // as you specify a parent activity in AndroidManifest.xml. 78 | int id = item.getItemId(); 79 | 80 | //noinspection SimplifiableIfStatement 81 | if (id == R.id.action_settings) { 82 | return true; 83 | } 84 | 85 | return super.onOptionsItemSelected(item); 86 | } 87 | 88 | @SuppressWarnings("StatementWithEmptyBody") 89 | @Override 90 | public boolean onNavigationItemSelected(MenuItem item) { 91 | // Handle navigation view item clicks here. 92 | int id = item.getItemId(); 93 | 94 | if (id == R.id.nav_camera) { 95 | // Handle the camera action 96 | } else if (id == R.id.nav_gallery) { 97 | 98 | } else if (id == R.id.nav_slideshow) { 99 | 100 | } else if (id == R.id.nav_manage) { 101 | 102 | } else if (id == R.id.nav_share) { 103 | 104 | } else if (id == R.id.nav_send) { 105 | 106 | } 107 | 108 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 109 | drawer.closeDrawer(GravityCompat.START); 110 | return true; 111 | } 112 | 113 | @Override 114 | protected void onDestroy() { 115 | super.onDestroy(); 116 | 117 | EventBus.getDefault().unregister(this); 118 | } 119 | 120 | private Fragment getCurrentFragment() { 121 | Fragment currentFragment = null; 122 | 123 | List fragmentList = getSupportFragmentManager().getFragments(); 124 | 125 | if(fragmentList != null) { 126 | for (Fragment fragment : fragmentList) { 127 | if (fragment != null && fragment.isVisible()) { 128 | currentFragment = fragment; 129 | 130 | break; 131 | } 132 | } 133 | } 134 | 135 | return currentFragment; 136 | } 137 | 138 | @Subscribe(threadMode = ThreadMode.MAIN) 139 | public void onEventMainThread(VideoEvents.OpenVideoGroup event) { 140 | LocalVideoFragment localVideoFragment = new LocalVideoFragment(); 141 | Bundle bundle = new Bundle(); 142 | bundle.putSerializable(VideoGroup.class.getSimpleName(), event.getVideoGroup()); 143 | localVideoFragment.setArguments(bundle); 144 | getSupportFragmentManager() 145 | .beginTransaction() 146 | .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) 147 | .hide(getCurrentFragment()) 148 | .add(R.id.fragment_container, localVideoFragment) 149 | .addToBackStack(null) 150 | .commit(); 151 | } 152 | 153 | @Subscribe(threadMode = ThreadMode.MAIN) 154 | public void onEventMainThread(VideoEvents.PlayLocalVideo event) { 155 | Intent intent = new Intent(MainActivity.this, VideoActivity.class); 156 | intent.putExtra(VideoInfo.class.getSimpleName(), event.getVideoInfo()); 157 | startActivity(intent); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/adapters/LocalVideoAdapter.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.adapters; 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.ImageButton; 9 | import android.widget.TextView; 10 | 11 | import com.nostra13.universalimageloader.core.ImageLoader; 12 | import com.shirlman.yiplayer.R; 13 | import com.shirlman.yiplayer.events.VideoEvents; 14 | import com.shirlman.yiplayer.models.VideoGroup; 15 | import com.shirlman.yiplayer.models.VideoInfo; 16 | import com.shirlman.yiplayer.util.FileUtils; 17 | import com.shirlman.yiplayer.util.StringUtils; 18 | 19 | import org.greenrobot.eventbus.EventBus; 20 | 21 | /** 22 | * Created by KB-Server on 2016/6/25. 23 | */ 24 | public class LocalVideoAdapter extends RecyclerView.Adapter { 25 | private VideoGroup mVideoGroup; 26 | private LayoutInflater mLayoutInflater; 27 | 28 | public LocalVideoAdapter(Context context, VideoGroup videoGroup) { 29 | mVideoGroup = videoGroup; 30 | mLayoutInflater = LayoutInflater.from(context); 31 | } 32 | 33 | @Override 34 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 35 | View rootView = mLayoutInflater.inflate(R.layout.local_video_item, parent, false); 36 | 37 | return new ViewHolder(rootView); 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(ViewHolder holder, int position) { 42 | final VideoInfo videoInfo = mVideoGroup.getVideoInfoList().get(position); 43 | 44 | ImageLoader.getInstance().displayImage("file://" + videoInfo.getThumbPath(), holder.videoThumb); 45 | 46 | holder.videoTitle.setText(videoInfo.getTitle()); 47 | holder.videoDuration.setText(StringUtils.getTimeDisplayString(videoInfo.getDuration())); 48 | holder.videoSize.setText(FileUtils.showFileSize(videoInfo.getSize())); 49 | 50 | holder.videoThumb.setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | EventBus.getDefault().post(new VideoEvents.PlayLocalVideo(videoInfo)); 54 | } 55 | }); 56 | } 57 | 58 | @Override 59 | public int getItemCount() { 60 | return mVideoGroup.getVideoInfoList().size(); 61 | } 62 | 63 | class ViewHolder extends RecyclerView.ViewHolder { 64 | public ImageButton videoThumb; 65 | public TextView videoTitle; 66 | public TextView videoSize; 67 | public TextView videoDuration; 68 | 69 | public ViewHolder(View itemView) { 70 | super(itemView); 71 | 72 | videoThumb = (ImageButton) itemView.findViewById(R.id.local_video_thumb); 73 | videoTitle = (TextView) itemView.findViewById(R.id.local_video_title); 74 | videoSize = (TextView) itemView.findViewById(R.id.local_video_info); 75 | videoDuration = (TextView) itemView.findViewById(R.id.local_video_duration); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/adapters/LocalVideoGroupAdapter.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.adapters; 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.ImageButton; 9 | import android.widget.TextView; 10 | 11 | import com.nostra13.universalimageloader.core.ImageLoader; 12 | import com.shirlman.yiplayer.R; 13 | import com.shirlman.yiplayer.events.VideoEvents; 14 | import com.shirlman.yiplayer.models.VideoGroup; 15 | import com.shirlman.yiplayer.models.VideoInfo; 16 | import com.shirlman.yiplayer.util.StringUtils; 17 | 18 | import org.greenrobot.eventbus.EventBus; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * Created by KB-Server on 2016/6/25. 24 | */ 25 | public class LocalVideoGroupAdapter extends RecyclerView.Adapter { 26 | private List mVideoGroupList; 27 | private LayoutInflater mLayoutInflater; 28 | 29 | public LocalVideoGroupAdapter(Context context, List videoGroupList) { 30 | mVideoGroupList = videoGroupList; 31 | mLayoutInflater = LayoutInflater.from(context); 32 | } 33 | 34 | @Override 35 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 36 | View rootView = mLayoutInflater.inflate(R.layout.local_video_item, parent, false); 37 | 38 | return new ViewHolder(rootView); 39 | } 40 | 41 | @Override 42 | public void onBindViewHolder(ViewHolder holder, int position) { 43 | final VideoGroup videoGroup = mVideoGroupList.get(position); 44 | VideoInfo firstVideoInfo = videoGroup.getVideoInfoList().get(0); 45 | 46 | ImageLoader.getInstance().displayImage("file://" + firstVideoInfo.getThumbPath(), holder.firstVideoThumb); 47 | 48 | holder.firstVideoDuration.setText(StringUtils.getTimeDisplayString(firstVideoInfo.getDuration())); 49 | holder.videoGroupName.setText(videoGroup.getGroupName()); 50 | 51 | String videoCount = String.format( 52 | holder.itemView.getResources().getString(R.string.local_video_count), 53 | videoGroup.getVideoInfoList().size()); 54 | holder.videoCount.setText(videoCount); 55 | 56 | holder.firstVideoThumb.setOnClickListener(new View.OnClickListener() { 57 | @Override 58 | public void onClick(View v) { 59 | EventBus.getDefault().post(new VideoEvents.OpenVideoGroup(videoGroup)); 60 | } 61 | }); 62 | } 63 | 64 | @Override 65 | public int getItemCount() { 66 | return mVideoGroupList.size(); 67 | } 68 | 69 | class ViewHolder extends RecyclerView.ViewHolder { 70 | public ImageButton firstVideoThumb; 71 | public TextView videoGroupName; 72 | public TextView videoCount; 73 | public TextView firstVideoDuration; 74 | 75 | public ViewHolder(View itemView) { 76 | super(itemView); 77 | 78 | firstVideoThumb = (ImageButton) itemView.findViewById(R.id.local_video_thumb); 79 | videoGroupName = (TextView) itemView.findViewById(R.id.local_video_title); 80 | videoCount = (TextView) itemView.findViewById(R.id.local_video_info); 81 | firstVideoDuration = (TextView) itemView.findViewById(R.id.local_video_duration); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/adapters/OnlineSubtitleAdapter.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.adapters; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.util.Log; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.TextView; 11 | 12 | import com.shirlman.yiplayer.R; 13 | import com.shirlman.yiplayer.core.OnlineQueryService; 14 | import com.shirlman.yiplayer.models.ShooterSubtitleDetailResponse; 15 | import com.shirlman.yiplayer.models.ShooterSubtitleResponse; 16 | import com.shirlman.yiplayer.util.StringUtils; 17 | 18 | import java.util.LinkedHashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | import retrofit2.Call; 23 | import retrofit2.Callback; 24 | import retrofit2.Response; 25 | import retrofit2.Retrofit; 26 | import retrofit2.converter.gson.GsonConverterFactory; 27 | 28 | /** 29 | * Created by KB-Server on 2016/7/24. 30 | */ 31 | public class OnlineSubtitleAdapter extends RecyclerView.Adapter { 32 | private LayoutInflater mLayoutInflater; 33 | private List mSubtitleList; 34 | 35 | private class OnDownloadClickListener implements View.OnClickListener { 36 | private String mSubtitleId; 37 | 38 | OnDownloadClickListener(String subtitleId) { 39 | mSubtitleId = subtitleId; 40 | } 41 | 42 | @Override 43 | public void onClick(View view) { 44 | String shooterBaseUrl = "http://api.assrt.net/v1/sub/detail/"; 45 | String shooterToken = "5fjG5Znw0KgfqL1QmDffB3A7qzaGAXzF"; 46 | 47 | Map searchFilters = new LinkedHashMap<>(); 48 | searchFilters.put("token", shooterToken); 49 | searchFilters.put("id", mSubtitleId); 50 | 51 | Retrofit retrofit = new Retrofit.Builder() 52 | .baseUrl(shooterBaseUrl) 53 | .addConverterFactory(GsonConverterFactory.create()) 54 | .build(); 55 | 56 | OnlineQueryService service = retrofit.create(OnlineQueryService.class); 57 | service.getSubtitleDetailFromShooter(searchFilters).enqueue(new Callback() { 58 | @Override 59 | public void onResponse(Call call, Response response) { 60 | if(response.isSuccessful() && response.body() != null && response.body().getSub() != null 61 | && response.body().getSub().getSubs() != null && response.body().getSub().getSubs().size() > 0) { 62 | String downloadUrl = response.body().getSub().getSubs().get(0).getUrl(); 63 | } 64 | } 65 | 66 | @Override 67 | public void onFailure(Call call, Throwable t) { 68 | Log.e("OnDownloadClickListener", "querySubtitleFromShooter.onFailure: ", t); 69 | } 70 | }); 71 | } 72 | } 73 | 74 | public OnlineSubtitleAdapter(Context context, List subtitleList) { 75 | mLayoutInflater = LayoutInflater.from(context); 76 | mSubtitleList = subtitleList; 77 | } 78 | 79 | @Override 80 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 81 | View rootView = mLayoutInflater.inflate(R.layout.online_subtitle_item, parent, false); 82 | 83 | return new ViewHolder(rootView); 84 | } 85 | 86 | @Override 87 | public void onBindViewHolder(ViewHolder holder, int position) { 88 | ShooterSubtitleResponse.SubBean.SubsBean subtitle = mSubtitleList.get(position); 89 | 90 | String title = StringUtils.nullOrEmpty(subtitle.getNative_name()) 91 | ? subtitle.getVideoname() : subtitle.getNative_name(); 92 | String language = subtitle.getLang() == null ? "未知" : subtitle.getLang().getDesc(); 93 | 94 | holder.title.setText(title); 95 | holder.voteScore.setText(subtitle.getVote_score()); 96 | holder.language.setText(language); 97 | holder.download.setOnClickListener(new OnDownloadClickListener(subtitle.getId())); 98 | } 99 | 100 | @Override 101 | public int getItemCount() { 102 | return mSubtitleList.size(); 103 | } 104 | 105 | class ViewHolder extends RecyclerView.ViewHolder { 106 | public TextView title; 107 | public TextView language; 108 | public TextView voteScore; 109 | private Button download; 110 | 111 | public ViewHolder(View itemView) { 112 | super(itemView); 113 | 114 | title = (TextView) itemView.findViewById(R.id.online_subtitle_title); 115 | language = (TextView) itemView.findViewById(R.id.online_subtitle_language); 116 | voteScore = (TextView) itemView.findViewById(R.id.online_subtitle_vote_score); 117 | download = (Button) itemView.findViewById(R.id.online_subtitle_download); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/fragments/LocalVideoFragment.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import com.shirlman.yiplayer.R; 13 | import com.shirlman.yiplayer.models.VideoGroup; 14 | import com.shirlman.yiplayer.ui.adapters.LocalVideoAdapter; 15 | 16 | /** 17 | * Created by KB-Server on 2016/6/24. 18 | */ 19 | public class LocalVideoFragment extends Fragment { 20 | private View mRootView; 21 | private RecyclerView mRecyclerView; 22 | 23 | @Nullable 24 | @Override 25 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 26 | super.onCreateView(inflater, container, savedInstanceState); 27 | 28 | VideoGroup videoGroup = (VideoGroup) getArguments().getSerializable(VideoGroup.class.getSimpleName()); 29 | 30 | mRootView = inflater.inflate(R.layout.local_video_fragment, container, false); 31 | 32 | GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2); 33 | mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.local_video_recycler_view); 34 | mRecyclerView.setLayoutManager(gridLayoutManager); 35 | mRecyclerView.setNestedScrollingEnabled(false); 36 | 37 | mRecyclerView.setAdapter(new LocalVideoAdapter(getActivity(), videoGroup)); 38 | 39 | return mRootView; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/fragments/LocalVideoGroupFragment.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import com.shirlman.yiplayer.MyApplication; 13 | import com.shirlman.yiplayer.R; 14 | import com.shirlman.yiplayer.events.VideoEvents; 15 | import com.shirlman.yiplayer.jobs.GetLocalVideoListJob; 16 | import com.shirlman.yiplayer.models.VideoGroup; 17 | import com.shirlman.yiplayer.ui.adapters.LocalVideoGroupAdapter; 18 | 19 | import org.greenrobot.eventbus.EventBus; 20 | import org.greenrobot.eventbus.Subscribe; 21 | import org.greenrobot.eventbus.ThreadMode; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * Created by KB-Server on 2016/6/25. 27 | */ 28 | public class LocalVideoGroupFragment extends Fragment{ 29 | private View mRootView; 30 | private RecyclerView mRecyclerView; 31 | 32 | @Nullable 33 | @Override 34 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 35 | super.onCreateView(inflater, container, savedInstanceState); 36 | 37 | EventBus.getDefault().register(this); 38 | 39 | MyApplication.getJobManager().addJobInBackground(new GetLocalVideoListJob()); 40 | 41 | mRootView = inflater.inflate(R.layout.local_video_fragment, container, false); 42 | 43 | GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2); 44 | mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.local_video_recycler_view); 45 | mRecyclerView.setLayoutManager(gridLayoutManager); 46 | mRecyclerView.setNestedScrollingEnabled(false); 47 | 48 | return mRootView; 49 | } 50 | 51 | @Override 52 | public void onDestroyView() { 53 | super.onDestroyView(); 54 | 55 | EventBus.getDefault().unregister(this); 56 | } 57 | 58 | @Subscribe(threadMode = ThreadMode.MAIN) 59 | public void onEventMainThread(VideoEvents.OnLocalVideoListGot event) { 60 | List videoGroupList = event.getVideoGroupList(); 61 | 62 | if(videoGroupList.size() > 0) { 63 | mRecyclerView.setAdapter(new LocalVideoGroupAdapter(getActivity(), videoGroupList)); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/ui/widgets/VideoController.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.ui.widgets; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | 7 | /** 8 | * Created by KB-Server on 2016/6/25. 9 | */ 10 | public class VideoController { 11 | private Context mContext; 12 | private View mRootView; 13 | private boolean isLocked; 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/shirlman/yiplayer/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.shirlman.yiplayer.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Locale; 7 | import java.util.TimeZone; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | public class StringUtils { 12 | private static final String TAG = StringUtils.class.getSimpleName(); 13 | 14 | public static boolean notNullNorEmpty(String str) { 15 | return str != null && !str.isEmpty(); 16 | } 17 | 18 | public static boolean nullOrEmpty(String str) { 19 | return str == null || str.isEmpty(); 20 | } 21 | 22 | public static String join(List list, String separator) { 23 | if(list == null || list.size() == 0) { 24 | return ""; 25 | } 26 | 27 | StringBuilder stringBuilder = new StringBuilder(); 28 | 29 | for (int i = 0; i < list.size(); i++) { 30 | stringBuilder.append(list.get(i)); 31 | 32 | if (i < list.size() - 1) { 33 | stringBuilder.append(separator); 34 | } 35 | } 36 | 37 | return stringBuilder.toString(); 38 | } 39 | 40 | public static String join(final ArrayList array, final String separator) { 41 | StringBuffer result = new StringBuffer(); 42 | 43 | if (array != null && array.size() > 0) { 44 | for (String str : array) { 45 | result.append(str); 46 | result.append(separator); 47 | } 48 | 49 | result.delete(result.length() - 1, result.length()); 50 | } 51 | 52 | return result.toString(); 53 | } 54 | 55 | public static String join(final String[] array, final String separator) { 56 | if(array == null || array.length == 0) { 57 | return ""; 58 | } 59 | 60 | StringBuilder stringBuilder = new StringBuilder(); 61 | 62 | for (int i = 0; i < array.length; i++) { 63 | stringBuilder.append(array[i]); 64 | 65 | if (i < array.length - 1) { 66 | stringBuilder.append(separator); 67 | } 68 | } 69 | 70 | return stringBuilder.toString(); 71 | } 72 | 73 | public static String getTimeDisplayString(long milliSeconds) { 74 | String timeFormat = milliSeconds > 60 * 60 * 1000 ? "HH:mm:ss" : "mm:ss"; 75 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormat, Locale.ENGLISH); 76 | simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); 77 | return simpleDateFormat.format(milliSeconds); 78 | } 79 | 80 | public static boolean isChineseChar(String str) { 81 | boolean temp = false; 82 | Pattern p = Pattern.compile("[\u4e00-\u9fa5]"); 83 | Matcher m = p.matcher(str); 84 | 85 | if (m.find()) { 86 | temp = true; 87 | } 88 | 89 | return temp; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_gallery.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_manage.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_slideshow.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/video_controller_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shirlman/YiPlayer/4da831ccde874afe4f308073fce981743d3a9221/app/src/main/res/drawable-v21/video_controller_lock.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/video_controller_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shirlman/YiPlayer/4da831ccde874afe4f308073fce981743d3a9221/app/src/main/res/drawable-v21/video_controller_next.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/video_controller_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shirlman/YiPlayer/4da831ccde874afe4f308073fce981743d3a9221/app/src/main/res/drawable-v21/video_controller_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/video_controller_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shirlman/YiPlayer/4da831ccde874afe4f308073fce981743d3a9221/app/src/main/res/drawable-v21/video_controller_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/video_controller_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shirlman/YiPlayer/4da831ccde874afe4f308073fce981743d3a9221/app/src/main/res/drawable-v21/video_controller_settings.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/local_video_info_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seek_bar_background_fill.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seek_bar_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seek_bar_progress_fill.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/video_controller_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/video_lock_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_bar_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/local_video_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 19 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/local_video_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 16 | 22 | 32 | 33 | 43 | 44 | 45 | 46 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout/nav_header_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 20 | 21 | 27 | 28 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/online_subtitle.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | 20 | 21 | 25 | 34 |