├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── jackchance │ │ └── live360 │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── jackchance │ │ │ └── live360 │ │ │ ├── Api │ │ │ └── DataApi.kt │ │ │ ├── Live360Application.kt │ │ │ ├── activity │ │ │ ├── APPInfoActivity.kt │ │ │ ├── BaseActivity.kt │ │ │ ├── CaptureActivity.java │ │ │ ├── HomeActivity.kt │ │ │ ├── JieVideoListViewAdapter.java │ │ │ ├── LiveDetailActivity.kt │ │ │ ├── LivePublishActivity.kt │ │ │ ├── LocalFragment.java │ │ │ ├── SpinnerHelper.java │ │ │ ├── SplashActivity.kt │ │ │ ├── TestVideoActivity.java │ │ │ └── VideoPlayerActivity.java │ │ │ ├── data │ │ │ ├── BaseData.kt │ │ │ ├── LiveInfo.kt │ │ │ ├── LiveMessage.kt │ │ │ └── LiveRoom.kt │ │ │ ├── fragment │ │ │ └── HomeMiscFragment.kt │ │ │ ├── live │ │ │ └── VRLiveActivity.kt │ │ │ ├── model │ │ │ ├── GetList.java │ │ │ ├── MyVideoThumbLoader.java │ │ │ ├── NetDbAdapter.java │ │ │ ├── NetbaseHelper.java │ │ │ ├── Strings.java │ │ │ ├── Translation.java │ │ │ └── User.kt │ │ │ ├── util │ │ │ ├── ActivityUtil.kt │ │ │ ├── Cpu.java │ │ │ ├── JsonUtil.kt │ │ │ ├── LoadedImage.java │ │ │ ├── MyImageEngine.kt │ │ │ ├── OSSHelper.kt │ │ │ ├── QosObject.java │ │ │ ├── QosThread.java │ │ │ ├── Settings.java │ │ │ ├── TimeUtil.kt │ │ │ ├── UiUtil.kt │ │ │ └── ViewUtil.kt │ │ │ ├── videolist │ │ │ ├── data │ │ │ │ ├── LiveData.kt │ │ │ │ ├── Publisher.kt │ │ │ │ ├── Video.java │ │ │ │ └── VideoListGetter.kt │ │ │ ├── fragement │ │ │ │ └── HomeLiveListFragment.kt │ │ │ └── ui │ │ │ │ └── MyVideoRecyclerViewAdapter.kt │ │ │ ├── vod │ │ │ ├── VodListFragment.kt │ │ │ ├── adapter │ │ │ │ ├── MyViewPagerAdapter.kt │ │ │ │ └── VodVideoRecyclerViewAdapter.kt │ │ │ ├── data │ │ │ │ ├── VodData.kt │ │ │ │ └── VodListGetter.kt │ │ │ └── fragement │ │ │ │ └── VodVideoListFragment.kt │ │ │ └── zxing │ │ │ ├── camera │ │ │ ├── AutoFocusCallback.java │ │ │ ├── CameraConfigurationManager.java │ │ │ ├── CameraManager.java │ │ │ ├── FlashlightManager.java │ │ │ ├── PlanarYUVLuminanceSource.java │ │ │ └── PreviewCallback.java │ │ │ ├── decoding │ │ │ ├── CaptureActivityHandler.java │ │ │ ├── DecodeFormatManager.java │ │ │ ├── DecodeHandler.java │ │ │ ├── DecodeThread.java │ │ │ ├── FinishListener.java │ │ │ ├── InactivityTimer.java │ │ │ └── Intents.java │ │ │ └── view │ │ │ ├── ViewfinderResultPointCallback.java │ │ │ └── ViewfinderView.java │ ├── libs │ │ ├── arm64-v8a │ │ │ └── libksyplayer.so │ │ ├── armeabi-v7a │ │ │ └── libksyplayer.so │ │ ├── libksyplayer.jar │ │ ├── libksystat.jar │ │ ├── vrlib.jar │ │ ├── x86 │ │ │ └── libksyplayer.so │ │ └── zxing.jar │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── background.png │ │ ├── button_bg_selector.xml │ │ ├── button_bg_shape_clicked.xml │ │ ├── button_bg_shape_enable_false.xml │ │ ├── button_bg_shape_enable_true.xml │ │ ├── ic_launcher_background.xml │ │ ├── icon_avtar.png │ │ ├── icon_home_360_inselected.png │ │ ├── icon_home_360_selseted.png │ │ ├── icon_home_live_inselected.png │ │ ├── icon_home_live_selected.png │ │ ├── icon_home_misc_selected.png │ │ ├── icon_home_misc_unselected.png │ │ ├── icon_home_publish_selected.png │ │ ├── icon_home_publish_unselected.png │ │ ├── icon_home_setting_selected.png │ │ ├── icon_home_setting_unselected.png │ │ ├── icon_live_publish.png │ │ ├── icon_misc_arrow.png │ │ ├── icon_misc_bt_bg_info.png │ │ ├── icon_new_version.png │ │ ├── icon_qr_code_scan.png │ │ ├── live360_background.jpg │ │ ├── logo_live_360.png │ │ ├── logo_white.png │ │ ├── qyvideo_pause_btn.png │ │ ├── qyvideo_start_btn.png │ │ ├── selector_home_kind_bg.xml │ │ ├── selector_home_misc_bg.xml │ │ ├── selector_home_publish_bg.xml │ │ ├── selector_home_setting_bg.xml │ │ ├── selector_home_video_list_bg.xml │ │ ├── shape_check_version_bt_bg.xml │ │ ├── shape_tips_button_bg.xml │ │ ├── splash_bg.jpg │ │ ├── video_bg_item.9.png │ │ └── video_image.png │ │ ├── layout │ │ ├── activity_appinfo.xml │ │ ├── activity_home.xml │ │ ├── activity_live.xml │ │ ├── activity_live_detail.xml │ │ ├── activity_md_using_surface_view.xml │ │ ├── activity_md_using_texture_view.xml │ │ ├── activity_player.xml │ │ ├── activity_splash.xml │ │ ├── camera.xml │ │ ├── fragement_video_list_for_tab.xml │ │ ├── fragement_vod_video_adapter_view.xml │ │ ├── fragment_home_misc.xml │ │ ├── fragment_live_publish.xml │ │ ├── fragment_local.xml │ │ ├── fragment_video_item.xml │ │ ├── fragment_video_list.xml │ │ ├── fragment_vod_list.xml │ │ ├── list_history.xml │ │ ├── list_local.xml │ │ ├── media_actionbar.xml │ │ ├── net_actionbar.xml │ │ ├── popup_layout.xml │ │ ├── qianyi_player.xml │ │ ├── simple_spinner_item.xml │ │ └── video_list_refresh_header_view.xml │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── beep.ogg │ │ └── realm_properties │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── network_security_config.xml │ └── test │ └── java │ └── com │ └── jackchance │ └── live360 │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── imgs ├── android_arch.png ├── demo1.png ├── demo2.png ├── demo3.png ├── demo4.png ├── demo5.png ├── insta360.png ├── panoramic_principle.png ├── panoramic_process.png ├── server_arch.png ├── system_arch.png └── viewer_process.png ├── keystore.jks └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | *.aab 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Log Files 28 | *.log 29 | 30 | # Android Studio Navigation editor temp files 31 | .navigation/ 32 | 33 | # Android Studio captures folder 34 | captures/ 35 | 36 | # IntelliJ 37 | *.iml 38 | .idea/workspace.xml 39 | .idea/tasks.xml 40 | .idea/gradle.xml 41 | .idea/assetWizardSettings.xml 42 | .idea/dictionaries 43 | .idea/libraries 44 | .idea/caches 45 | # Android Studio 3 in .gitignore file. 46 | .idea/caches/build_file_checksums.ser 47 | .idea/modules.xml 48 | .idea/misc.xml 49 | 50 | # Keystore files 51 | # Uncomment the following lines if you do not want to check your keystore files in. 52 | #*.jks 53 | #*.keystore 54 | 55 | # External native build folder generated in Android Studio 2.2 and later 56 | .externalNativeBuild 57 | 58 | # Google Services (e.g. APIs or Firebase) 59 | # google-services.json 60 | 61 | # Freeline 62 | freeline.py 63 | freeline/ 64 | freeline_project_description.json 65 | 66 | # fastlane 67 | fastlane/report.xml 68 | fastlane/Preview.html 69 | fastlane/screenshots 70 | fastlane/test_output 71 | fastlane/readme.md 72 | 73 | # Version control 74 | vcs.xml 75 | 76 | # lint 77 | lint/intermediates/ 78 | lint/generated/ 79 | lint/outputs/ 80 | lint/tmp/ 81 | # lint/reports/ 82 | 83 | .DS_Store 84 | .idea/codeStyles/ 85 | .idea/runConfigurations.xml 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Live360 移动全景视频直播系统 2 | 3 | ### 前言 4 | 5 | - 关于开发实现,没什么好记录的,倒是整个调研和复杂系统的设计过程比较有意思。 6 | - 2020.06补充:虽然现在看觉得方案还有很多不完善的地方,但确实是本科阶段设计的比较复杂的系统了,挺有纪念意义。 7 | 8 | ### 关于Live360 9 | 10 | Live360系统以功能一体化的全景相机(Insta360)作为前端采集设备,通过RTMP协议将全景画面推流到流媒体服务器并通过安卓客户端进行直播拉流和全景播放。同时流媒体服务器还进行了流转码、流存储以及支持HLS直播等流处理操作以支持直播清晰度切换、回放以及网页端播放等常用功能。 11 | 12 | 本项目为Live360系统安卓端APP项目 13 | 14 | 其他相关项目: 15 | 1. SRS流媒体服务器:[SRS](https://github.com/ossrs/srs), Live360所采用的开源流媒体服务器,感谢大佬们,解决我大难题,国产开源之光。 16 | 2. 管理前端项目地址:[Live360Manager](https://github.com/ZWboy97/Live360Manager) 17 | 1. 网页全景播放项目:[Live360WebPlayer](https://github.com/ZWboy97/Live360WebPlayer) 18 | 1. 后端服务器项目地址:[Live360Server](https://github.com/ZWboy97/live360Server) 19 | 1. 安卓端项目地址:[Live360Android](https://github.com/ZWboy97/Live360) 20 | 21 | ### Insta360全景相机 22 | - Live360所采用的全景相机,可以连接智能手机,进行直播推流。 23 | - Insta360地址:[Insta360 One 官网](https://www.insta360.com/product/insta360-one/) 24 | ![Insta360全景相机图](./imgs/insta360.png) 25 | 26 |
27 | 28 | 1) 全景图片:分辨率6912*3456,输出格式INSP、JPG、RAW。 29 | 2) 全景视频:分辨率@帧率3840*1920@30fps、2560*1280@60fps、 2048*512@120fps,输出格式:INSV、MP4。 30 | 3) 全景直播:支持RTMP推流、支持推流到常用社交媒体以及自定义直播地址、码率可选1Mbps-8Mbps、帧率30fps、分辨率可选720P、1080P、1440P。 31 | 4) 其它支持:机内拼接、蓝牙4.0、通过Type-C或者Lighting接口连接智能手机、锂电池移动拍摄等。 32 | 33 | - 再放两个图,关于全景原理以及全景渲染流程的 34 | ![全景原理](./imgs/panoramic_principle.png) 35 |
36 | 37 | ![全景处理流程](./imgs/panoramic_process.png) 38 |
39 | 40 | ### Live360系统架构 41 | 完整的系统架构图 42 | 43 | ![系统架构图](./imgs/system_arch.png) 44 | 45 |
46 | 47 | 对于全景视频采集部分,使用目前市面上已有的消费级功能一体化全景相机作为前端采集设备(Insta360),通过连接智能手机完成全景采集、拼接、投影、编码以及推流等一系列流程。智能手机通过RTMP流媒体协议将全景画面推流到流媒体服务器,全景播放端通过RTMP或者HLS协议拉流并进行全景渲染。 48 | 49 | 为了支持全景直播的多码率切换以及直播回放功能,在流媒体服务器上需要部署流转码与流录制服务。流转码服务将直播流转码成更低码率和分辨率的一路新的直播流,与原始流一同可以被用户端拉流播放。流录制功能实现将直播流录制成视频文件以实现直播的回放点播功能,由于视频的点播服务同样需要占用大量的网络带宽,为了减轻流媒体服务器的网络压力,目标系统使用阿里云等公有云提供的OSS服务存储直播录制的视频文件。 50 | 51 | 应用服务器上部署了目标系统的后台数据库,同时部署Restful Api服务为客户端提供后台数据支持。推荐将目标系统的应用服务器与流媒体服务器分开部署在两个主机上,使得应用服务器服务质量不受流媒体服务器流量波动的影响,以保障即便在直播服务不响应的情况下用户端直播信息功能模块依然能正常使用。 52 | 53 | 对于直播监控管理Web平台,为了获得实时同步的直播监控数据,其后端数据服务将主要由流媒体服务器提供。而对于涉及账号、鉴权等功能,流媒体服务器通过网络回调远程调用应用服务器上提供的账号验证与鉴权功能。 54 | 55 | 56 | ### Live360流媒体服务器 57 | 流媒体服务器基于大名鼎鼎的[SRS](https://github.com/ossrs/srs)开源流媒体服务器开发,国产开源之光,感谢大佬们提供的开源解决方案,采用SRS基本一个互联网直播平台需要的能力基本都能实现,较难的是实现支持大规模直播分发以及低时延等优化和运营。 58 | 流媒体部分使用到了SRS提供的流录制、流转码、HLS切片、HTTP-API、回调接口等能力。录制到阿里云OSS的部分,通过OSS的SDK实现。 59 | 60 | ![服务器端架构](./imgs/server_arch.png) 61 | 62 |
63 | 64 | 对直播时延进行了测试,能做到两秒的延时。 65 | 66 | ![直播时延测试](./imgs/demo5.png) 67 | 68 | 69 | ### Live360安卓端 70 | 安卓端全景播放器,自己撸是不会自己撸的,依然得抱紧开源大佬的腿,感谢开源项目[MD360Player](https://github.com/ashqal/MD360Player4Android)的大佬们。 71 | 72 | 安卓端是花费时间比较多的部分,自己也进行了比较充分的架构设计,也用上了Retroift、Kotlin等新东西。 73 | ![安卓端架构](./imgs/android_arch.png) 74 | 75 | 76 | ### Live360管理端 77 | 管理端主要基于SRS流媒体服务器提供的Http-API接口作为后端数据来源,提供了流监控、流预览、流踢出等功能。前端部分采用React框架进行开发,界面采用了蚂蚁金服的[Ant Design](https://ant.design/index-cn)。 78 | 79 | ### Live360后端 80 | 后端基于Spring框架开发,直接上了SpringBoot,第一次上手,感觉还挺有呀,十分好用。 81 | 82 | ### 网页端全景播放 83 | 没错,当然还是抱紧开源大佬的大腿拉,基于video.js提供的开源播放器库,直播协议采用的hls。 84 | 整个开发过程还好,唯一蛋疼的是hls是基于HTTP的,所以会存在跨域问题,这个问题可以阻挠了我好一阵,逼得我把HTTP给学了一通,现在反过来看,当时自己咋就被这么个问题给干趴下了,不就一个google的事嘛? 85 | 86 | ### 系统演示 87 | - 安卓APP 88 | 89 | ![demo1](./imgs/demo1.png) 90 |
91 | 92 | ![demo2](./imgs/demo2.png) 93 | 94 | - 管理端 95 | 96 | ![demo3](./imgs/demo3.png) 97 | 98 | - Web全景播放器 99 | 100 | ![demo4](./imgs/demo4.png) -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 28 9 | defaultConfig { 10 | applicationId "com.jackchance.live360" 11 | minSdkVersion 21 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "1.0.0" 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | debug { 19 | versionNameSuffix ".dev" 20 | } 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | sourceSets.main { 27 | jniLibs.srcDirs 'src/main/libs' 28 | jni.srcDirs = [] // This prevents the auto generation of Android.mk 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(dir: 'libs', include: ['*.jar']) 34 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 35 | implementation 'com.android.support:appcompat-v7:28.0.0' 36 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 37 | 38 | implementation fileTree(include: ['*.jar'], dir: 'libs') 39 | implementation fileTree(include: '*/so', dir: 'libs/armeabi-v7a') 40 | implementation fileTree(include: '*/so', dir: 'libs/arm64-v8a') 41 | implementation fileTree(include: '*/so', dir: 'libs/x86') 42 | implementation files('src/main/libs/zxing.jar') 43 | implementation files('src/main/libs/vrlib.jar') 44 | implementation files('src/main/libs/libksyplayer.jar') 45 | implementation files('src/main/libs/libksystat.jar') 46 | 47 | implementation 'com.android.support:support-v4:28.0.0' 48 | implementation 'com.android.support:recyclerview-v7:28.0.0' 49 | implementation 'com.squareup.picasso:picasso:2.71828' 50 | implementation 'de.hdodenhof:circleimageview:2.1.0' 51 | implementation 'com.github.Aspsine:IRecyclerView:0.0.5' 52 | implementation 'com.squareup.okhttp3:okhttp:3.10.0' 53 | implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.2' 54 | implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.2' 55 | 56 | implementation 'io.reactivex:rxjava:1.2.0' 57 | implementation 'io.reactivex:rxandroid:1.1.0' 58 | implementation 'com.squareup.retrofit2:retrofit:2.3.0' 59 | implementation 'com.squareup.retrofit2:converter-gson:2.3.0' 60 | implementation 'com.squareup.retrofit2:adapter-rxjava:2.2.0' 61 | implementation 'com.google.code.gson:gson:2.8.2' 62 | implementation 'com.android.support:design:28.0.0' 63 | 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 67 | 68 | // pandora 69 | debugImplementation('com.github.whataa:pandora:1.2.2') { 70 | exclude group: "com.squareup.okhttp3" 71 | } 72 | releaseImplementation('com.github.whataa:pandora-no-op:1.2.2') { 73 | exclude group: "com.squareup.okhttp3" 74 | } 75 | 76 | // mmkv 77 | implementation 'com.tencent:mmkv:1.0.16' 78 | 79 | //Matissse 80 | implementation 'com.zhihu.android:matisse:0.4.3' 81 | 82 | implementation 'pub.devrel:easypermissions:2.0.1' 83 | 84 | implementation 'com.aliyun.dpa:oss-android-sdk:+' 85 | 86 | implementation 'com.jzxiang.pickerview:TimePickerDialog:1.0.1' 87 | 88 | 89 | } 90 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -dontwarn com.squareup.picasso.** 23 | -dontwarn com.bumptech.glide.** 24 | -keep class com.alibaba.sdk.android.oss.** { *; } 25 | -dontwarn okio.** 26 | -dontwarn org.apache.commons.codec.binary.** 27 | 28 | -keep class com.ksyun.media.player.**{ *; } 29 | -keep class com.ksy.statlibrary.**{ *;} -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/androidTest/java/com/jackchance/live360/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.jackchance.live360 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.jackchance.live360", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 31 | 32 | 33 | 36 | 37 | 40 | 43 | 44 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 58 | 65 | 70 | 74 | 75 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/jackchance/live360/Api/DataApi.kt: -------------------------------------------------------------------------------- 1 | package com.jackchance.live360.Api 2 | 3 | import com.jackchance.live360.data.LiveMessage 4 | import com.jackchance.live360.data.LiveRoom 5 | import com.jackchance.live360.model.Translation 6 | import okhttp3.OkHttpClient 7 | import retrofit2.Call 8 | import retrofit2.Retrofit 9 | import retrofit2.converter.gson.GsonConverterFactory 10 | import retrofit2.http.Body 11 | import retrofit2.http.GET 12 | import retrofit2.http.POST 13 | import tech.linjiang.pandora.Pandora 14 | 15 | /** 16 | * Created by lijiachang on 2018/11/26 17 | */ 18 | object DataApi { 19 | 20 | val okHttpClient = OkHttpClient.Builder().addInterceptor(Pandora.get().interceptor).build() 21 | 22 | private val dataService: DataService = Retrofit.Builder() 23 | .client(okHttpClient) 24 | .baseUrl("http://39.106.194.43:8080/live360/") 25 | .addConverterFactory(GsonConverterFactory.create()) 26 | .build() 27 | .create(DataService::class.java) 28 | 29 | private interface DataService { 30 | 31 | @POST("livemessages/") 32 | fun postLiveMessage(@Body liveMessage: LiveMessage): Call 33 | 34 | @GET("livemessages/") 35 | fun getLiveMessages(): Call 36 | 37 | @POST("liverooms/") 38 | fun postLiveRooms(@Body liveRoom: LiveRoom): Call 39 | 40 | @GET("liverooms/") 41 | fun getLiveRooms(): Call> 42 | 43 | } 44 | 45 | fun postLiveMessage(liveMessage: LiveMessage): Call { 46 | return dataService.postLiveMessage(liveMessage) 47 | } 48 | 49 | fun getLiveMessages(): Call { 50 | return dataService.getLiveMessages() 51 | } 52 | 53 | fun postLiveRooms(liveRoom: LiveRoom): Call { 54 | return dataService.postLiveRooms(liveRoom) 55 | } 56 | 57 | fun getLiveRooms(): Call> { 58 | return dataService.getLiveRooms() 59 | } 60 | 61 | 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/jackchance/live360/Live360Application.kt: -------------------------------------------------------------------------------- 1 | package com.jackchance.live360 2 | 3 | import android.app.Application 4 | import com.jackchance.live360.util.OSSHelper 5 | 6 | class Live360Application : Application() { 7 | 8 | override fun onCreate() { 9 | super.onCreate() 10 | OSSHelper.initOSS(applicationContext) 11 | } 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/jackchance/live360/activity/APPInfoActivity.kt: -------------------------------------------------------------------------------- 1 | package com.jackchance.live360.activity 2 | 3 | import android.support.v7.app.AppCompatActivity 4 | import android.os.Bundle 5 | import android.widget.Button 6 | import android.widget.TextView 7 | import com.jackchance.live360.R 8 | import com.jackchance.live360.util.viewById 9 | import com.jackchance.live360.util.visible 10 | 11 | class APPInfoActivity : AppCompatActivity() { 12 | 13 | private val checkVersionButton: Button by viewById(R.id.check_version_button) 14 | private val messageText: TextView by viewById(R.id.message_text) 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setContentView(R.layout.activity_appinfo) 19 | checkVersionButton.setOnClickListener { 20 | checkVersionButton.visible = false 21 | messageText.visible = true 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/jackchance/live360/activity/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.jackchance.live360.activity 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | 6 | /** 7 | * Created by lijiachang on 2018/11/19 8 | */ 9 | open class BaseActivity : AppCompatActivity(){ 10 | 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/jackchance/live360/activity/JieVideoListViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.jackchance.live360.activity; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | 11 | import com.jackchance.live360.model.MyVideoThumbLoader; 12 | import com.jackchance.live360.videolist.data.Video; 13 | import com.jackchance.live360.R; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class JieVideoListViewAdapter extends BaseAdapter { 19 | 20 | private ArrayList