Skip to content
This repository was archived by the owner on Sep 24, 2023. It is now read-only.

Commit 3cbe36c

Browse files
committed
1.字幕模块全部完成;
1 parent bc44be6 commit 3cbe36c

19 files changed

+1482
-10
lines changed

app/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ android {
3838

3939
defaultConfig {
4040
applicationId "net.zentring.live"
41-
minSdkVersion 26
41+
minSdkVersion 29
4242
targetSdkVersion 30
4343
versionCode getMyVersionCode()
4444
versionName getMyVersionName()
@@ -103,4 +103,5 @@ dependencies {
103103
implementation 'com.google.code.gson:gson:2.8.6'
104104
//等待框动画用
105105
implementation 'com.nineoldandroids:library:2.4.0'
106+
implementation 'org.xutils:xutils:3.5.1'
106107
}

app/src/main/AndroidManifest.xml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
android:required="false" />
1717

1818
<application
19+
android:name="net.zentring.live.common.BaseApp"
1920
android:allowBackup="true"
2021
android:icon="@mipmap/ic_launcher"
2122
android:label="@string/app_name"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package net.zentring.live
2+
3+
enum class GraphicType() {
4+
HIT, RANK
5+
}

app/src/main/java/net/zentring/live/GraphicView.kt

+69-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.zentring.live
22

33
import android.content.Context
4+
import android.text.TextUtils
45
import android.util.AttributeSet
56
import android.util.Log
67
import android.view.View
@@ -22,7 +23,7 @@ import kotlinx.android.synthetic.main.graphic_view.view.*
2223
import net.zentring.live.CustomLoadingView.ShapeLoadingDialog
2324
import net.zentring.live.adapter.RankAdapter
2425

25-
class GraphicView @JvmOverloads constructor(
26+
open class GraphicView @JvmOverloads constructor(
2627
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
2728
) : ConstraintLayout(context, attrs, defStyleAttr) {
2829

@@ -137,6 +138,11 @@ class GraphicView @JvmOverloads constructor(
137138
undo()
138139
}
139140

141+
//上字幕
142+
up_graphic_btn.setOnClickListener {
143+
upGraphic()
144+
}
145+
140146
getHitGraphicData()
141147
}
142148

@@ -270,9 +276,6 @@ class GraphicView @JvmOverloads constructor(
270276
}
271277
}
272278

273-
fun setHitBtnFlowLayoutData() {
274-
}
275-
276279
private fun savePlace(placeID: Int) {
277280
if (selectedPlayerIndex == -1) {
278281
Toast.makeText(mContext, "请先选择球员", Toast.LENGTH_SHORT).show()
@@ -437,4 +440,66 @@ class GraphicView @JvmOverloads constructor(
437440
queue.add(stringRequest)
438441
}
439442
}
443+
444+
private fun upGraphic() {
445+
mLoadingDialog.show()
446+
var url: String = ""
447+
var code = ""
448+
if (nowPreviewGraphicType == 1) {
449+
val holeID = hitGraphicData?.data?.mh_id
450+
val hitNumber = hitGraphicData?.data?.sc_score
451+
val playerName = hitGraphicData?.data?.pl_cn_name
452+
val score = hitGraphicData?.data?.su_to_par
453+
val rank = hitGraphicData?.data?.su_rank
454+
val holePar = hitGraphicData?.data?.mh_par
455+
val totalYard = hitGraphicData?.data?.mh_tee
456+
val prevTee = hitGraphicData?.data?.prev_tee
457+
val prevLeftTee = hitGraphicData?.data?.prev_left_tee
458+
val prevScPlace = hitGraphicData?.data?.prev_sc_place
459+
val prevScGolfClub = hitGraphicData?.data?.prev_sc_golf_club
460+
code = "info"
461+
url = data.API_BASE_URL + "live_png.php?code=${code}&pl_cn_name=${playerName}&sc_to_par=${score}&sc_rank=${rank}" +
462+
"&sc_score=${hitNumber}&ho_id=${holeID}&mh_par=${holePar}&mh_tee=${totalYard}&prev_tee=${prevTee}&prev_left_tee=${prevLeftTee}" +
463+
"&prev_sc_place=${prevScPlace}&prev_sc_golf_club=${prevScGolfClub}"
464+
} else {
465+
code = "rank"
466+
val rankJsonString = Gson().toJson(rankList)
467+
url = data.API_BASE_URL + "live_png.php?code=${code}&list=${rankJsonString}"
468+
}
469+
Log.e("zhaofei", url)
470+
val stringRequest = StringRequest(
471+
Request.Method.GET, url,
472+
Response.Listener<String> { response ->
473+
Log.e("zhaofei", response)
474+
val graphicVo = Gson().fromJson(response, GraphicVo::class.java)
475+
if (graphicVo == null) {
476+
Toast.makeText(mContext, "生成击球字幕失败", Toast.LENGTH_SHORT).show()
477+
} else {
478+
if (!TextUtils.isEmpty(graphicVo.url)) {
479+
if (::graphicListener.isInitialized) {
480+
if (nowPreviewGraphicType == 1) {
481+
graphicListener(GraphicType.HIT, graphicVo.url, graphicVo.time)
482+
} else {
483+
graphicListener(GraphicType.RANK, graphicVo.url, graphicVo.time)
484+
}
485+
}
486+
} else {
487+
Toast.makeText(mContext, "生成击球字幕失败", Toast.LENGTH_SHORT).show()
488+
}
489+
}
490+
mLoadingDialog.dismiss()
491+
},
492+
Response.ErrorListener {
493+
mLoadingDialog.dismiss()
494+
Toast.makeText(mContext, "生成击球字幕失败", Toast.LENGTH_SHORT).show()
495+
it.printStackTrace()
496+
}
497+
)
498+
queue.add(stringRequest)
499+
}
500+
501+
private lateinit var graphicListener: (GraphicType, String, Long) -> Unit
502+
fun setGraphicListener(listener: (GraphicType, String, Long) -> Unit) {
503+
this@GraphicView.graphicListener = listener
504+
}
440505
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package net.zentring.live
2+
3+
class GraphicVo {
4+
var url: String = ""
5+
var time //字幕停留时间
6+
: Long = 5000
7+
}

app/src/main/java/net/zentring/live/LiveActivity.kt

+129-5
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,19 @@ import com.pedro.encoder.input.decoder.VideoDecoderInterface
3333
import com.pedro.encoder.input.gl.render.filters.AndroidViewFilterRender
3434
import com.pedro.encoder.input.gl.render.filters.BlackFilterRender
3535
import com.pedro.encoder.input.gl.render.filters.NoFilterRender
36+
import com.pedro.encoder.input.gl.render.filters.`object`.ImageObjectFilterRender
3637
import com.pedro.encoder.input.video.CameraHelper
38+
import com.pedro.encoder.utils.gl.TranslateTo
3739
import com.pedro.rtplibrary.rtmp.RtmpCamera1
3840
import com.pedro.rtplibrary.rtmp.RtmpFromFile
3941
import idv.luchafang.videotrimmer.VideoTrimmerView
4042
import kotlinx.android.synthetic.main.activity_live.*
4143
import net.ossrs.rtmp.ConnectCheckerRtmp
44+
import net.zentring.live.common.Common
45+
import net.zentring.live.common.MathUtils
4246
import net.zentring.live.data.Companion.instance
47+
import net.zentring.live.graphic.HitGraphic
48+
import net.zentring.live.graphic.RankGraphic
4349
import java.io.File
4450
import java.io.FileOutputStream
4551
import java.io.InputStream
@@ -383,11 +389,115 @@ class LiveActivity : AppCompatActivity(), ConnectCheckerRtmp, SurfaceHolder.Call
383389

384390
edit.setOnClickListener {
385391
graphic_view.show()
392+
graphic_view.setGraphicListener { graphicType: GraphicType, url: String, time: Long ->
393+
upGraphic(graphicType, url, time)
394+
}
386395
graphic_view.bringToFront()
387396
settingBtn.visibility = View.INVISIBLE
388397
}
389398
}
390399

400+
private fun upGraphic(graphicType: GraphicType, url: String, time: Long) {
401+
when (graphicType) {
402+
GraphicType.HIT -> upHitGraphic(url, time)
403+
GraphicType.RANK -> upRankGraphic(url, time)
404+
}
405+
}
406+
407+
private fun upHitGraphic(url: String, time: Long) {
408+
val graphicID = 1
409+
val hitGraphic = HitGraphic()
410+
hitGraphic.onStatusListener { whetherUp, path, width, height ->
411+
if (whetherUp == Common.WHETHER_UP_GRAPHIC_STATUS.can.toNumber()) {
412+
413+
val hitGraphicRender = ImageObjectFilterRender()
414+
hitGraphicRender.setImage(Common.getBitmap(path))
415+
//一定要先设置setScale,才可以用TranslateTo设置setPosition
416+
hitGraphicRender.setScale(
417+
MathUtils.div(width.toDouble(), data.resolution[0].toDouble())
418+
.toFloat() * 100 * 2,
419+
MathUtils.div(height.toDouble(), data.resolution[1].toDouble())
420+
.toFloat() * 100 * 2
421+
)
422+
hitGraphicRender.setPosition(TranslateTo.TOP_RIGHT)
423+
Log.e(
424+
"zhaofei",
425+
"width" + MathUtils.div(width.toDouble(), data.resolution[0].toDouble())
426+
.toString()
427+
)
428+
Log.e(
429+
"zhaofei",
430+
"height" + MathUtils.div(height.toDouble(), data.resolution[1].toDouble())
431+
.toString()
432+
)
433+
// rtmpCamera1!!.glInterface.setFilter(NoFilterRender())
434+
rtmpCamera1!!.glInterface.setFilter(graphicID, hitGraphicRender)
435+
clearGraphic(graphicID, 0, time)
436+
} else {
437+
Toast.makeText(applicationContext, "下载字幕失败!!!", Toast.LENGTH_SHORT).show()
438+
// setBtnEnableStatus(prizeGraphicBtn, true)
439+
}
440+
}
441+
hitGraphic.useGraphic(url)
442+
}
443+
444+
private fun upRankGraphic(url: String, time: Long) {
445+
val graphicID = 2
446+
val rankGraphic = RankGraphic()
447+
rankGraphic.onStatusListener { whetherUp, path, width, height ->
448+
if (whetherUp == Common.WHETHER_UP_GRAPHIC_STATUS.can.toNumber()) {
449+
450+
val rankGraphicRender = ImageObjectFilterRender()
451+
rankGraphicRender.setImage(Common.getBitmap(path))
452+
//一定要先设置setScale,才可以用TranslateTo设置setPosition
453+
rankGraphicRender.setScale(
454+
MathUtils.div(width.toDouble(), data.resolution[0].toDouble())
455+
.toFloat() * 100 * 2,
456+
MathUtils.div(height.toDouble(), data.resolution[1].toDouble())
457+
.toFloat() * 100 * 2
458+
)
459+
rankGraphicRender.setPosition(TranslateTo.CENTER)
460+
Log.e(
461+
"zhaofei",
462+
"width" + MathUtils.div(width.toDouble(), data.resolution[0].toDouble())
463+
.toString()
464+
)
465+
Log.e(
466+
"zhaofei",
467+
"height" + MathUtils.div(height.toDouble(), data.resolution[1].toDouble())
468+
.toString()
469+
)
470+
// rtmpCamera1!!.glInterface.setFilter(NoFilterRender())
471+
rtmpCamera1!!.glInterface.setFilter(graphicID, rankGraphicRender)
472+
clearGraphic(graphicID, 0, time)
473+
} else {
474+
Toast.makeText(applicationContext, "下载字幕失败!!!", Toast.LENGTH_SHORT).show()
475+
// setBtnEnableStatus(prizeGraphicBtn, true)
476+
}
477+
}
478+
rankGraphic.useGraphic(url)
479+
}
480+
481+
private var mTimer //定时下字幕
482+
: Timer? = null
483+
484+
private fun clearGraphic(
485+
id: Int,
486+
btn: Int,
487+
time: Long
488+
) {
489+
if (mTimer == null) {
490+
mTimer = Timer()
491+
}
492+
val timerTask: TimerTask = object : TimerTask() {
493+
override fun run() {
494+
// rtmpCamera1!!.glInterface.setFilter(NoFilterRender())
495+
rtmpCamera1!!.glInterface.setFilter(id, NoFilterRender())
496+
}
497+
}
498+
mTimer!!.schedule(timerTask, time)
499+
}
500+
391501
private fun returnToLive() {
392502
if (rtmpFile!!.isStreaming) {
393503
rtmpFile!!.stopStream()
@@ -636,7 +746,20 @@ class LiveActivity : AppCompatActivity(), ConnectCheckerRtmp, SurfaceHolder.Call
636746
var i = 0
637747
Thread {
638748
while (true) {
639-
rtmpCamera1!!.startRecord(File(part, i.toString()).absolutePath)
749+
/*
750+
java.lang.IllegalArgumentException
751+
at android.media.MediaCodec.native_configure(Native Method)
752+
at android.media.MediaCodec.configure(MediaCodec.java:2023)
753+
at android.media.MediaCodec.configure(MediaCodec.java:1951)
754+
at com.pedro.encoder.video.VideoEncoder.prepareVideoEncoder(VideoEncoder.java:128)
755+
at com.pedro.encoder.video.VideoEncoder.reset(VideoEncoder.java:196)
756+
at com.pedro.rtplibrary.base.Camera1Base.resetVideoEncoder(Camera1Base.java:484)
757+
at com.pedro.rtplibrary.base.Camera1Base.startRecord(Camera1Base.java:287)
758+
at com.pedro.rtplibrary.base.Camera1Base.startRecord(Camera1Base.java:293)
759+
at net.zentring.live.LiveActivity$startStreaming$2.run(LiveActivity.kt:675)
760+
at java.lang.Thread.run(Thread.java:929)
761+
*/
762+
// rtmpCamera1!!.startRecord(File(part, i.toString()).absolutePath)
640763
Thread.sleep(1000)
641764
rtmpCamera1!!.stopRecord()
642765
i++
@@ -748,8 +871,8 @@ class LiveActivity : AppCompatActivity(), ConnectCheckerRtmp, SurfaceHolder.Call
748871
rtmpCamera1!!.prepareVideo(
749872
data.resolution[0],
750873
data.resolution[1],
751-
30,
752-
12000 * 1024,
874+
25,
875+
5000 * 1024,
753876
false,
754877
rotation
755878
)
@@ -959,8 +1082,8 @@ class LiveActivity : AppCompatActivity(), ConnectCheckerRtmp, SurfaceHolder.Call
9591082
}
9601083

9611084
private fun setDefaultPreviewSize() {
962-
val r = 1920.0 / 1080
963-
data.resolution = arrayOf(1920, 1080)
1085+
val r = 1280.0 / 720
1086+
data.resolution = arrayOf(1280, 720)
9641087
setCameraScale(r)
9651088
}
9661089

@@ -1295,6 +1418,7 @@ class LiveActivity : AppCompatActivity(), ConnectCheckerRtmp, SurfaceHolder.Call
12951418
}
12961419

12971420
override fun onDestroy() {
1421+
mTimer?.cancel()
12981422
super.onDestroy()
12991423
this.releaseInstance()
13001424
finishAffinity()

app/src/main/java/net/zentring/live/Utils.kt

+16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.zentring.live
22

3+
import android.os.Environment
34
import android.text.TextUtils
5+
import java.io.File
46

57
class Utils {
68
companion object StaticParams {
@@ -27,5 +29,19 @@ class Utils {
2729
}
2830
return str
2931
}
32+
33+
val SD_DIR =
34+
Environment.getExternalStorageDirectory().path
35+
val RESOURCE_DIR = "/situne/live"
36+
37+
@JvmStatic
38+
fun getHitGraphicPath(): String {
39+
return "$SD_DIR$RESOURCE_DIR/graphic/hit/"
40+
}
41+
42+
@JvmStatic
43+
fun getRankGraphicPath(): String {
44+
return "$SD_DIR$RESOURCE_DIR/graphic/rank/"
45+
}
3046
}
3147
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package net.zentring.live.common;
2+
3+
import android.app.Application;
4+
5+
import net.zentring.live.data;
6+
7+
import org.xutils.x;
8+
9+
public class BaseApp extends Application {
10+
@Override
11+
public void onCreate() {
12+
super.onCreate();
13+
14+
x.Ext.init(this);
15+
x.Ext.setDebug(false);
16+
}
17+
}

0 commit comments

Comments
 (0)