11package com.tencent.iot.explorer.link.demo.video.preview
22
3+ import android.Manifest
34import android.graphics.SurfaceTexture
5+ import android.media.AudioFormat
46import android.os.Bundle
57import android.os.Handler
68import android.os.Message
@@ -9,23 +11,35 @@ import android.util.DisplayMetrics
911import android.util.Log
1012import android.view.Surface
1113import android.view.TextureView
14+ import android.view.View
1215import android.view.WindowManager
1316import android.widget.Toast
17+ import com.alibaba.fastjson.JSONArray
18+ import com.tencent.iot.explorer.link.demo.App
1419import com.tencent.iot.explorer.link.demo.R
1520import com.tencent.iot.explorer.link.demo.VideoBaseActivity
1621import com.tencent.iot.explorer.link.demo.common.log.L
1722import com.tencent.iot.explorer.link.demo.common.util.CommonUtils
23+ import com.tencent.iot.explorer.link.demo.common.util.ImageSelect
1824import com.tencent.iot.explorer.link.demo.video.Command
25+ import com.tencent.iot.explorer.link.demo.video.DevInfo
26+ import com.tencent.iot.explorer.link.demo.video.playback.VideoPlaybackActivity
1927import com.tencent.iot.explorer.link.demo.video.utils.TipToastDialog
28+ import com.tencent.iot.explorer.link.demo.video.utils.ToastDialog
29+ import com.tencent.iot.video.link.util.audio.AudioRecordUtil
2030import com.tencent.xnet.XP2P
2131import com.tencent.xnet.XP2PCallback
32+ import kotlinx.android.synthetic.main.activity_video_preview.iv_down
33+ import kotlinx.android.synthetic.main.activity_video_preview.iv_left
34+ import kotlinx.android.synthetic.main.activity_video_preview.iv_right
35+ import kotlinx.android.synthetic.main.activity_video_preview.iv_up
2236import kotlinx.android.synthetic.main.activity_video_preview.layout_video_preview
37+ import kotlinx.android.synthetic.main.activity_video_preview.radio_photo
38+ import kotlinx.android.synthetic.main.activity_video_preview.radio_playback
39+ import kotlinx.android.synthetic.main.activity_video_preview.radio_record
40+ import kotlinx.android.synthetic.main.activity_video_preview.radio_talk
2341import kotlinx.android.synthetic.main.activity_video_preview.tv_video_quality
2442import 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
2943import kotlinx.android.synthetic.main.dash_board_layout.tv_a_cache
3044import kotlinx.android.synthetic.main.dash_board_layout.tv_tcp_speed
3145import kotlinx.android.synthetic.main.dash_board_layout.tv_v_cache
@@ -59,22 +73,46 @@ open class VideoTestActivity : VideoBaseActivity(), XP2PCallback, CoroutineScope
5973 var showTip = false
6074 var firstIn = true
6175 val MSG_UPDATE_HUD = 1
76+ var permissions = arrayOf(Manifest .permission.RECORD_AUDIO )
77+ var filePath: String? = null
78+ var audioRecordUtil: AudioRecordUtil ? = null
6279
63- override fun onCreate (savedInstanceState : Bundle ? ) {
64- super .onCreate(savedInstanceState)
65- XP2P .setCallback(this )
66- }
80+ @Volatile
81+ var speakAble = false
6782
6883 override fun getContentView (): Int {
6984 return R .layout.activity_video_test
7085 }
7186
7287 override fun initView () {
88+ productId = intent.getStringExtra(" productId" )?.toString() ? : " "
89+ deviceName = intent.getStringExtra(" deviceName" )?.toString() ? : " "
90+ xp2pInfo = intent.getStringExtra(" p2pInfo" )?.toString() ? : " "
91+ audioRecordUtil = AudioRecordUtil (this , " ${productId} /${deviceName} " , 16000 , AudioFormat .CHANNEL_IN_MONO , AudioFormat .ENCODING_PCM_16BIT )
92+ XP2P .setCallback(this )
93+ XP2P .startService(this , " ${productId} /${deviceName} " , productId, deviceName)
94+
95+ val ret = XP2P .setParamsForXp2pInfo(
96+ " ${productId} /${deviceName} " , " " , " " , xp2pInfo
97+ )
98+ if (ret != 0 ) {
99+ launch(Dispatchers .Main ) {
100+ val errInfo: String
101+ if (ret.toString() == " -1007" ) {
102+ errInfo = getString(R .string.xp2p_err_version)
103+ } else {
104+ errInfo = getString(
105+ R .string.error_with_code,
106+ " ${productId} /${deviceName} " ,
107+ ret.toString()
108+ )
109+ }
110+ Toast .makeText(this @VideoTestActivity, errInfo, Toast .LENGTH_SHORT ).show()
111+ }
112+ }
113+
73114 tv_video_quality.text = " 高清"
74115 v_preview.surfaceTextureListener = this
75- et_product_id.setText(productId)
76- et_device_name.setText(deviceName)
77- et_p2p_info.setText(xp2pInfo)
78116 val wm = this .getSystemService(WINDOW_SERVICE ) as WindowManager
79117 val dm = DisplayMetrics ()
80118 wm.defaultDisplay.getMetrics(dm)
@@ -86,44 +124,117 @@ open class VideoTestActivity : VideoBaseActivity(), XP2PCallback, CoroutineScope
86124 }
87125
88126 override fun setListener () {
89- btn_connect.setOnClickListener {
90- if (et_product_id.text.isNullOrEmpty()) {
91- show(" 请输入productId" )
92- return @setOnClickListener
127+ radio_talk.setOnCheckedChangeListener { buttonView, isChecked ->
128+ if (isChecked && checkPermissions(permissions)) {
129+ if (! speakAble(true )) radio_talk.isChecked = false
130+ } else if (isChecked && ! checkPermissions(permissions)) {
131+ requestPermission(permissions)
132+ } else {
133+ speakAble(false )
93134 }
94- if (et_device_name.text.isNullOrEmpty()) {
95- show(" 请输入deviceName" )
96- return @setOnClickListener
135+ }
136+ radio_record.setOnCheckedChangeListener { buttonView, isChecked ->
137+ if (isChecked) {
138+ filePath = CommonUtils .generateFileDefaultPath()
139+ var ret = player.startRecord(filePath)
140+ if (ret != 0 ) {
141+ ToastDialog (
142+ this ,
143+ ToastDialog .Type .WARNING ,
144+ getString(R .string.record_failed),
145+ 2000
146+ ).show()
147+ radio_record.isChecked = false
148+ }
149+ } else {
150+ player.stopRecord()
151+ CommonUtils .refreshVideoList(this @VideoTestActivity, filePath)
97152 }
98- if (et_p2p_info.text.isNullOrEmpty()) {
99- show(" 请输入P2PInfo" )
100- return @setOnClickListener
153+ }
154+ radio_playback.setOnClickListener {
155+ val dev = DevInfo ()
156+ dev.DeviceName = deviceName
157+ VideoPlaybackActivity .startPlaybackActivity(this @VideoTestActivity, dev)
158+ }
159+ radio_photo.setOnClickListener {
160+ val bitmap = v_preview.getBitmap(player.videoWidth, player.videoHeight)
161+ ImageSelect .saveBitmap(this @VideoTestActivity, bitmap)
162+ ToastDialog (
163+ this ,
164+ ToastDialog .Type .SUCCESS ,
165+ getString(R .string.capture_successed),
166+ 2000
167+ ).show()
168+ }
169+ iv_up.setOnClickListener(controlListener)
170+ iv_down.setOnClickListener(controlListener)
171+ iv_right.setOnClickListener(controlListener)
172+ iv_left.setOnClickListener(controlListener)
173+ }
174+
175+ open var controlListener = object : View .OnClickListener {
176+ override fun onClick (v : View ? ) {
177+ var command = " "
178+ when (v) {
179+ iv_up -> command = Command .getPtzUpCommand(0 )
180+ iv_down -> command = Command .getPtzDownCommand(0 )
181+ iv_right -> command = Command .getPtzRightCommand(0 )
182+ iv_left -> command = Command .getPtzLeftCommand(0 )
101183 }
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 ) {
184+
185+ Thread (Runnable {
186+ if (command.length <= 0 ) return @Runnable
187+ var retContent = XP2P .postCommandRequestSync(
188+ " ${productId} /${deviceName} " ,
189+ command.toByteArray(), command.toByteArray().size.toLong(), 2 * 1000 * 1000
190+ ) ? : " "
112191 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- )
192+ if (TextUtils .isEmpty(retContent)) {
193+ retContent = getString(R .string.command_with_error, command)
122194 }
123- Toast .makeText(this @VideoTestActivity, errInfo, Toast .LENGTH_SHORT ).show()
195+ Toast .makeText(this @VideoTestActivity, retContent, Toast .LENGTH_SHORT ).show()
196+ }
197+ }).start()
198+ }
199+ }
200+
201+ open fun speakAble (able : Boolean ): Boolean {
202+ if (able) {
203+ val command = Command .getNvrIpcStatus(0 , 0 )
204+ val repStatus = XP2P .postCommandRequestSync(
205+ " ${productId} /${deviceName} " ,
206+ command.toByteArray(), command.toByteArray().size.toLong(), 2 * 1000 * 1000
207+ ) ? : " "
208+
209+ launch(Dispatchers .Main ) {
210+ var retContent = StringBuilder (repStatus).toString()
211+ if (TextUtils .isEmpty(retContent)) {
212+ retContent = getString(R .string.command_with_error, command)
124213 }
214+ Toast .makeText(this @VideoTestActivity, retContent, Toast .LENGTH_SHORT ).show()
125215 }
216+
217+ JSONArray .parseArray(repStatus, DevStatus ::class .java)?.let {
218+ if (it.size == 1 && it.get(0 ).status == 0 ) {
219+ XP2P .runSendService(
220+ " ${productId} /${deviceName} " ,
221+ Command .getTwoWayRadio(0 ),
222+ true
223+ )
224+ audioRecordUtil?.start()
225+ speakAble = true
226+ return true
227+ }
228+ }
229+
230+ } else {
231+ speakAble = false
232+ audioRecordUtil?.stop()
233+ XP2P .stopSendService(" ${productId} /${deviceName} " , null )
234+ return true
126235 }
236+ speakAble = false
237+ return false
127238 }
128239
129240 private fun resetPlayer () {
0 commit comments