1
+ package io.agora.ktvapi
2
+
3
+ import android.util.Log
4
+ import io.agora.rtc2.Constants
5
+ import io.agora.rtc2.RtcEngine
6
+ import org.json.JSONObject
7
+ import java.util.HashMap
8
+
9
+ enum class APIType (val value : Int ) {
10
+ KTV (1 ), // K歌
11
+ CALL (2 ), // 呼叫连麦
12
+ BEAUTY (3 ), // 美颜
13
+ VIDEO_LOADER (4 ), // 秒开秒切
14
+ PK (5 ), // 团战
15
+ VIRTUAL_SPACE (6 ), //
16
+ SCREEN_SPACE (7 ), // 屏幕共享
17
+ AUDIO_SCENARIO (8 ) // 音频
18
+ }
19
+
20
+ enum class ApiEventType (val value : Int ) {
21
+ API (0 ),
22
+ COST (1 ),
23
+ CUSTOM (2 )
24
+ }
25
+
26
+ object ApiEventKey {
27
+ const val TYPE = " type"
28
+ const val DESC = " desc"
29
+ const val API_VALUE = " apiValue"
30
+ const val TIMESTAMP = " ts"
31
+ const val EXT = " ext"
32
+ }
33
+
34
+ object ApiCostEvent {
35
+ const val CHANNEL_USAGE = " channelUsage" // 频道使用耗时
36
+ const val FIRST_FRAME_ACTUAL = " firstFrameActual" // 首帧实际耗时
37
+ const val FIRST_FRAME_PERCEIVED = " firstFramePerceived" // 首帧感官耗时
38
+ }
39
+
40
+ class APIReporter (
41
+ private val type : APIType ,
42
+ private val version : String ,
43
+ private val rtcEngine : RtcEngine
44
+ ) {
45
+ private val tag = " APIReporter"
46
+ private val messageId = " agora:scenarioAPI"
47
+ private val durationEventStartMap = HashMap <String , Long >()
48
+ private val category = " ${type.value} _Android_$version "
49
+
50
+ init {
51
+ configParameters()
52
+ }
53
+
54
+ // 上报普通场景化API
55
+ fun reportFuncEvent (name : String , value : Map <String , Any >, ext : Map <String , Any >) {
56
+ Log .d(tag, " reportFuncEvent: $name value: $value ext: $ext " )
57
+ val eventMap = mapOf (ApiEventKey .TYPE to ApiEventType .API .value, ApiEventKey .DESC to name)
58
+ val labelMap = mapOf (ApiEventKey .API_VALUE to value, ApiEventKey .TIMESTAMP to getCurrentTs(), ApiEventKey .EXT to ext)
59
+ val event = convertToJSONString(eventMap) ? : " "
60
+ val label = convertToJSONString(labelMap) ? : " "
61
+ rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0 )
62
+ }
63
+
64
+ fun startDurationEvent (name : String ) {
65
+ Log .d(tag, " startDurationEvent: $name " )
66
+ durationEventStartMap[name] = getCurrentTs()
67
+ }
68
+
69
+ fun endDurationEvent (name : String , ext : Map <String , Any >) {
70
+ Log .d(tag, " endDurationEvent: $name " )
71
+ val beginTs = durationEventStartMap[name] ? : return
72
+ durationEventStartMap.remove(name)
73
+ val ts = getCurrentTs()
74
+ val cost = (ts - beginTs).toInt()
75
+
76
+ innerReportCostEvent(ts, name, cost, ext)
77
+ }
78
+
79
+ // 上报耗时打点信息
80
+ fun reportCostEvent (name : String , cost : Int , ext : Map <String , Any >) {
81
+ durationEventStartMap.remove(name)
82
+ innerReportCostEvent(
83
+ ts = getCurrentTs(),
84
+ name = name,
85
+ cost = cost,
86
+ ext = ext
87
+ )
88
+ }
89
+
90
+ // 上报自定义信息
91
+ fun reportCustomEvent (name : String , ext : Map <String , Any >) {
92
+ Log .d(tag, " reportCustomEvent: $name ext: $ext " )
93
+ val eventMap = mapOf (ApiEventKey .TYPE to ApiEventType .CUSTOM .value, ApiEventKey .DESC to name)
94
+ val labelMap = mapOf (ApiEventKey .TIMESTAMP to getCurrentTs(), ApiEventKey .EXT to ext)
95
+ val event = convertToJSONString(eventMap) ? : " "
96
+ val label = convertToJSONString(labelMap) ? : " "
97
+ rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0 )
98
+ }
99
+
100
+ fun writeLog (content : String , level : Int ) {
101
+ rtcEngine.writeLog(level, content)
102
+ }
103
+
104
+ fun cleanCache () {
105
+ durationEventStartMap.clear()
106
+ }
107
+
108
+ // ---------------------- private ----------------------
109
+
110
+ private fun configParameters () {
111
+ // rtcEngine.setParameters("{\"rtc.qos_for_test_purpose\": true}") //测试环境使用
112
+ // 数据上报
113
+ rtcEngine.setParameters(" {\" rtc.direct_send_custom_event\" : true}" )
114
+ // 日志写入
115
+ rtcEngine.setParameters(" {\" rtc.log_external_input\" : true}" )
116
+ }
117
+
118
+ private fun getCurrentTs (): Long {
119
+ return System .currentTimeMillis()
120
+ }
121
+
122
+ private fun innerReportCostEvent (ts : Long , name : String , cost : Int , ext : Map <String , Any >) {
123
+ Log .d(tag, " reportCostEvent: $name cost: $cost ms ext: $ext " )
124
+ writeLog(" reportCostEvent: $name cost: $cost ms" , Constants .LOG_LEVEL_INFO )
125
+ val eventMap = mapOf (ApiEventKey .TYPE to ApiEventType .COST .value, ApiEventKey .DESC to name)
126
+ val labelMap = mapOf (ApiEventKey .TIMESTAMP to ts, ApiEventKey .EXT to ext)
127
+ val event = convertToJSONString(eventMap) ? : " "
128
+ val label = convertToJSONString(labelMap) ? : " "
129
+ rtcEngine.sendCustomReportMessage(messageId, category, event, label, cost)
130
+ }
131
+
132
+ private fun convertToJSONString (dictionary : Map <String , Any >): String? {
133
+ return try {
134
+ JSONObject (dictionary).toString()
135
+ } catch (e: Exception ) {
136
+ writeLog(" [$tag ]convert to json fail: $e dictionary: $dictionary " , Constants .LOG_LEVEL_WARNING )
137
+ null
138
+ }
139
+ }
140
+ }
0 commit comments