Skip to content

Commit d5c5b58

Browse files
committed
增加test
1 parent 4571777 commit d5c5b58

File tree

6 files changed

+561
-31
lines changed

6 files changed

+561
-31
lines changed

sdkdemo/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
<activity android:name=".video.VideoOptionsActivity" />
5757
<activity android:name=".video.VideoInputAuthorizeActivity" />
5858
<activity android:name=".video.VideoWlanDetectActivity" />
59+
<activity android:name=".video.preview.VideoTestActivity" />
5960
<activity android:name=".video.preview.WlanVideoPreviewActivity"
6061
android:configChanges="orientation|keyboardHidden|screenSize"/>
6162
<activity android:name=".video.VideoMainActivity" />

sdkdemo/src/main/java/com/tencent/iot/explorer/link/demo/video/VideoOptionsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.tencent.iot.explorer.link.demo.video
33
import com.tencent.iot.explorer.link.demo.R
44
import com.tencent.iot.explorer.link.demo.BaseActivity
55
import com.tencent.iot.explorer.link.demo.VideoBaseActivity
6+
import com.tencent.iot.explorer.link.demo.video.preview.VideoTestActivity
67
import kotlinx.android.synthetic.main.activity_video_options.*
78

89
class VideoOptionsActivity : VideoBaseActivity() {
@@ -15,6 +16,7 @@ class VideoOptionsActivity : VideoBaseActivity() {
1516
override fun setListener() {
1617
btn_video.setOnClickListener { jumpActivity(VideoInputAuthorizeActivity::class.java) }
1718
btn_video_wlan.setOnClickListener { jumpActivity(VideoWlanDetectActivity::class.java) }
19+
btn_video_test.setOnClickListener { jumpActivity(VideoTestActivity::class.java) }
1820
}
1921

2022
}
Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
package com.tencent.iot.explorer.link.demo.video.preview
2+
3+
import android.graphics.SurfaceTexture
4+
import android.os.Bundle
5+
import android.os.Handler
6+
import android.os.Message
7+
import android.text.TextUtils
8+
import android.util.DisplayMetrics
9+
import android.util.Log
10+
import android.view.Surface
11+
import android.view.TextureView
12+
import android.view.WindowManager
13+
import android.widget.Toast
14+
import com.tencent.iot.explorer.link.demo.R
15+
import com.tencent.iot.explorer.link.demo.VideoBaseActivity
16+
import com.tencent.iot.explorer.link.demo.common.log.L
17+
import com.tencent.iot.explorer.link.demo.common.util.CommonUtils
18+
import com.tencent.iot.explorer.link.demo.video.Command
19+
import com.tencent.iot.explorer.link.demo.video.utils.TipToastDialog
20+
import com.tencent.xnet.XP2P
21+
import com.tencent.xnet.XP2PCallback
22+
import kotlinx.android.synthetic.main.activity_video_preview.layout_video_preview
23+
import kotlinx.android.synthetic.main.activity_video_preview.tv_video_quality
24+
import kotlinx.android.synthetic.main.activity_video_preview.v_preview
25+
import kotlinx.android.synthetic.main.activity_video_test.btn_connect
26+
import kotlinx.android.synthetic.main.activity_video_test.et_device_name
27+
import kotlinx.android.synthetic.main.activity_video_test.et_p2p_info
28+
import kotlinx.android.synthetic.main.activity_video_test.et_product_id
29+
import kotlinx.android.synthetic.main.dash_board_layout.tv_a_cache
30+
import kotlinx.android.synthetic.main.dash_board_layout.tv_tcp_speed
31+
import kotlinx.android.synthetic.main.dash_board_layout.tv_v_cache
32+
import kotlinx.android.synthetic.main.dash_board_layout.tv_video_w_h
33+
import kotlinx.coroutines.CoroutineScope
34+
import kotlinx.coroutines.Dispatchers
35+
import kotlinx.coroutines.MainScope
36+
import kotlinx.coroutines.cancel
37+
import kotlinx.coroutines.delay
38+
import kotlinx.coroutines.launch
39+
import org.json.JSONObject
40+
import tv.danmaku.ijk.media.player.IMediaPlayer
41+
import tv.danmaku.ijk.media.player.IjkMediaPlayer
42+
import java.lang.ref.WeakReference
43+
import java.util.Locale
44+
45+
open class VideoTestActivity : VideoBaseActivity(), XP2PCallback, CoroutineScope by MainScope(),
46+
TextureView.SurfaceTextureListener,
47+
IMediaPlayer.OnInfoListener {
48+
private val player = IjkMediaPlayer()
49+
lateinit var surface: Surface
50+
private var productId = ""
51+
private var deviceName = ""
52+
private var xp2pInfo = ""
53+
var urlPrefix = ""
54+
var screenWidth = 0
55+
var screenHeight = 0
56+
var startShowVideoTime = 0L
57+
var showVideoTime = 0L
58+
var connectTime = 0L
59+
var showTip = false
60+
var firstIn = true
61+
val MSG_UPDATE_HUD = 1
62+
63+
override fun onCreate(savedInstanceState: Bundle?) {
64+
super.onCreate(savedInstanceState)
65+
XP2P.setCallback(this)
66+
}
67+
68+
override fun getContentView(): Int {
69+
return R.layout.activity_video_test
70+
}
71+
72+
override fun initView() {
73+
tv_video_quality.text = "高清"
74+
v_preview.surfaceTextureListener = this
75+
et_product_id.setText(productId)
76+
et_device_name.setText(deviceName)
77+
et_p2p_info.setText(xp2pInfo)
78+
val wm = this.getSystemService(WINDOW_SERVICE) as WindowManager
79+
val dm = DisplayMetrics()
80+
wm.defaultDisplay.getMetrics(dm)
81+
val width = dm.widthPixels // 屏幕宽度(像素)
82+
val height = dm.heightPixels // 屏幕高度(像素)
83+
val density = dm.density // 屏幕密度(0.75 / 1.0 / 1.5)
84+
screenWidth = (width / density).toInt() // 屏幕宽度(dp)
85+
screenHeight = (height / density).toInt() // 屏幕高度(dp)
86+
}
87+
88+
override fun setListener() {
89+
btn_connect.setOnClickListener {
90+
if (et_product_id.text.isNullOrEmpty()) {
91+
show("请输入productId")
92+
return@setOnClickListener
93+
}
94+
if (et_device_name.text.isNullOrEmpty()) {
95+
show("请输入deviceName")
96+
return@setOnClickListener
97+
}
98+
if (et_p2p_info.text.isNullOrEmpty()) {
99+
show("请输入P2PInfo")
100+
return@setOnClickListener
101+
}
102+
productId = et_product_id.text.toString()
103+
deviceName = et_device_name.text.toString()
104+
xp2pInfo = et_p2p_info.text.toString()
105+
XP2P.startService(
106+
this@VideoTestActivity, "${productId}/${deviceName}", productId, deviceName
107+
)
108+
val ret = XP2P.setParamsForXp2pInfo(
109+
"${productId}/${deviceName}", "", "", xp2pInfo
110+
)
111+
if (ret != 0) {
112+
launch(Dispatchers.Main) {
113+
val errInfo: String
114+
if (ret.toString() == "-1007") {
115+
errInfo = getString(R.string.xp2p_err_version)
116+
} else {
117+
errInfo = getString(
118+
R.string.error_with_code,
119+
"${productId}/${deviceName}",
120+
ret.toString()
121+
)
122+
}
123+
Toast.makeText(this@VideoTestActivity, errInfo, Toast.LENGTH_SHORT).show()
124+
}
125+
}
126+
}
127+
}
128+
129+
private fun resetPlayer() {
130+
when (tv_video_quality.text.toString()) {
131+
getString(R.string.video_quality_high_str) -> setPlayerUrl(
132+
Command.getVideoSuperQualityUrlSuffix(
133+
0
134+
)
135+
)
136+
137+
getString(R.string.video_quality_medium_str) -> setPlayerUrl(
138+
Command.getVideoHightQualityUrlSuffix(
139+
0
140+
)
141+
)
142+
143+
getString(R.string.video_quality_low_str) -> setPlayerUrl(
144+
Command.getVideoStandardQualityUrlSuffix(
145+
0
146+
)
147+
)
148+
}
149+
}
150+
151+
open fun setPlayerUrl(suffix: String) {
152+
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500)
153+
showTip = false
154+
startShowVideoTime = System.currentTimeMillis()
155+
launch(Dispatchers.Main) {
156+
layout_video_preview?.removeView(v_preview)
157+
layout_video_preview?.addView(v_preview, 0)
158+
player.setOnInfoListener(this@VideoTestActivity)
159+
player.let {
160+
val url = urlPrefix + suffix
161+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 50 * 1024)
162+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0)
163+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1)
164+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "threads", 1)
165+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync-av-start", 0)
166+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1)
167+
it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1)
168+
it.setOption(
169+
IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1
170+
)
171+
172+
it.setFrameSpeed(1.5f)
173+
while (!::surface.isInitialized) {
174+
delay(50)
175+
L.e("delay for waiting surface.")
176+
}
177+
it.setSurface(surface)
178+
it.dataSource = url
179+
180+
it.prepareAsync()
181+
it.start()
182+
}
183+
}
184+
}
185+
186+
override fun fail(msg: String?, errorCode: Int) {
187+
188+
}
189+
190+
override fun commandRequest(id: String?, msg: String?) {
191+
Log.e("VideoTestActivity", "xp2pEventNotify id:$id msg:$msg")
192+
}
193+
194+
override fun xp2pEventNotify(id: String?, msg: String?, event: Int) {
195+
Log.e("VideoTestActivity", "xp2pEventNotify id:$id msg:$msg event:$event")
196+
if (event == 1004 || event == 1005) {
197+
if (event == 1004) {
198+
Log.e("VideoTestActivity", "====event === 1004")
199+
XP2P.delegateHttpFlv(id)?.let {
200+
urlPrefix = it
201+
if (!TextUtils.isEmpty(urlPrefix)) {
202+
resetPlayer()
203+
}
204+
}
205+
}
206+
}
207+
}
208+
209+
override fun avDataRecvHandle(id: String?, data: ByteArray?, len: Int) {
210+
Log.e("VideoTestActivity", "avDataRecvHandle id:$id data:$data len:$data")
211+
}
212+
213+
override fun avDataCloseHandle(id: String?, msg: String?, errorCode: Int) {
214+
Log.e("VideoTestActivity", "avDataCloseHandle id:$id msg:$msg errorCode:$errorCode")
215+
}
216+
217+
override fun onDeviceMsgArrived(id: String?, data: ByteArray?, len: Int): String {
218+
Log.e("VideoTestActivity", "onDeviceMsgArrived id:$id data:$data len:$len")
219+
val reply = JSONObject()
220+
reply.put("code", "0")
221+
reply.put("msg", "test command reply")
222+
return reply.toString()
223+
}
224+
225+
override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
226+
surface?.let {
227+
this.surface = Surface(surface)
228+
player.setSurface(this.surface)
229+
}
230+
}
231+
232+
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {
233+
val layoutParams = v_preview.layoutParams
234+
layoutParams.width = (player.videoWidth * (screenWidth * 16 / 9)) / player.videoHeight
235+
layoutParams.height = layoutParams.height
236+
v_preview.layoutParams = layoutParams
237+
}
238+
239+
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
240+
return false
241+
}
242+
243+
override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
244+
if (!showTip && startShowVideoTime > 0) {
245+
showVideoTime = System.currentTimeMillis() - startShowVideoTime
246+
val content =
247+
getString(R.string.time_2_show, connectTime.toString(), showVideoTime.toString())
248+
TipToastDialog(this, content, 10000).show()
249+
showTip = true
250+
}
251+
if (firstIn) {
252+
val layoutParams = v_preview.layoutParams
253+
layoutParams.width = (player.videoWidth * (screenWidth * 16 / 9)) / player.videoHeight
254+
layoutParams.height = layoutParams.height
255+
v_preview.layoutParams = layoutParams
256+
firstIn = false
257+
}
258+
}
259+
260+
override fun onInfo(p0: IMediaPlayer?, p1: Int, p2: Int): Boolean {
261+
return true
262+
}
263+
264+
override fun onInfoSEI(p0: IMediaPlayer?, p1: Int, p2: Int, p3: String?): Boolean {
265+
return false
266+
}
267+
268+
override fun onInfoAudioPcmData(p0: IMediaPlayer?, p1: ByteArray?, p2: Int) {
269+
}
270+
271+
private val mHandler = MyHandler(this)
272+
273+
private class MyHandler(activity: VideoTestActivity) : Handler() {
274+
private val mActivity: WeakReference<VideoTestActivity> = WeakReference(activity)
275+
override fun handleMessage(msg: Message) {
276+
if (mActivity.get() == null) {
277+
return
278+
}
279+
val activity = mActivity.get()
280+
when (msg.what) {
281+
activity?.MSG_UPDATE_HUD -> {
282+
activity.updateDashboard()
283+
removeMessages(activity.MSG_UPDATE_HUD)
284+
sendEmptyMessageDelayed(activity.MSG_UPDATE_HUD, 500)
285+
}
286+
}
287+
}
288+
}
289+
290+
private fun updateDashboard() {
291+
val videoCachedDuration = player.videoCachedDuration
292+
val audioCachedDuration = player.audioCachedDuration
293+
val videoCachedBytes = player.videoCachedBytes
294+
val audioCachedBytes = player.audioCachedBytes
295+
val tcpSpeed = player.tcpSpeed
296+
297+
tv_a_cache?.text = String.format(
298+
Locale.US, "%s, %s",
299+
CommonUtils.formatedDurationMilli(audioCachedDuration),
300+
CommonUtils.formatedSize(audioCachedBytes)
301+
)
302+
tv_v_cache?.text = String.format(
303+
Locale.US, "%s, %s",
304+
CommonUtils.formatedDurationMilli(videoCachedDuration),
305+
CommonUtils.formatedSize(videoCachedBytes)
306+
)
307+
tv_tcp_speed?.text = String.format(
308+
Locale.US, "%s",
309+
CommonUtils.formatedSpeed(tcpSpeed, 1000)
310+
)
311+
tv_video_w_h?.text = "${player.videoWidth} x ${player.videoHeight}"
312+
}
313+
314+
override fun onDestroy() {
315+
super.onDestroy()
316+
finishPlayer()
317+
XP2P.stopService("${productId}/${deviceName}")
318+
XP2P.setCallback(null)
319+
cancel()
320+
}
321+
322+
private fun finishPlayer() {
323+
mHandler.removeMessages(MSG_UPDATE_HUD)
324+
player.release()
325+
}
326+
}

0 commit comments

Comments
 (0)