Dana
2025-11-30 5a5240e9db90474d8da4e20d241246d3f1fa2950
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
package com.anyun.h264.service;
 
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
 
import com.anyun.h264.IH264EncodeService;
import com.anyun.h264.model.ResourceInfo;
 
import java.util.List;
 
/**
 * H264编码服务客户端
 * 用于绑定服务并调用AIDL接口
 * 
 * 使用示例:
 * <pre>
 * // 创建客户端
 * H264EncodeServiceClient client = new H264EncodeServiceClient(context);
 * 
 * // 绑定服务
 * client.bindService();
 * 
 * // 等待服务绑定完成后,调用接口
 * // 开启文件编码(带配置参数)
 * String jsonConfig = "{\"width\":640,\"height\":480,\"framerate\":25}";
 * int result = client.controlEncode(0, jsonConfig);
 * 
 * // 开启网络推送(带配置参数)
 * String networkConfig = "{\"ip\":\"192.168.1.100\",\"port\":8888,\"width\":1280,\"height\":720,\"framerate\":30}";
 * result = client.controlEncode(2, networkConfig);
 * 
 * // 停止编码(不需要配置参数)
 * client.controlEncode(1, null);
 * 
 * // 获取资源列表
 * List<ResourceInfo> resources = client.getResourceList("240101000000", "240101235959");
 * 
 * // 解绑服务
 * client.unbindService();
 * </pre>
 */
public class H264EncodeServiceClient {
    private static final String TAG = "H264EncodeClient";
    
    private Context context;
    private IH264EncodeService service;
    private boolean isBound = false;
    
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            Log.d(TAG, "Service connected");
            service = IH264EncodeService.Stub.asInterface(binder);
            isBound = true;
            
            // 可以在这里添加服务连接成功的回调
            if (onServiceConnectedListener != null) {
                onServiceConnectedListener.onConnected();
            }
        }
        
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "Service disconnected");
            service = null;
            isBound = false;
            
            // 可以在这里添加服务断开连接的回调
            if (onServiceDisconnectedListener != null) {
                onServiceDisconnectedListener.onDisconnected();
            }
        }
    };
    
    // 服务连接回调接口
    public interface OnServiceConnectedListener {
        void onConnected();
    }
    
    public interface OnServiceDisconnectedListener {
        void onDisconnected();
    }
    
    private OnServiceConnectedListener onServiceConnectedListener;
    private OnServiceDisconnectedListener onServiceDisconnectedListener;
    
    public H264EncodeServiceClient(Context context) {
        this.context = context.getApplicationContext();
    }
    
    /**
     * 设置服务连接监听器
     */
    public void setOnServiceConnectedListener(OnServiceConnectedListener listener) {
        this.onServiceConnectedListener = listener;
    }
    
    /**
     * 设置服务断开连接监听器
     */
    public void setOnServiceDisconnectedListener(OnServiceDisconnectedListener listener) {
        this.onServiceDisconnectedListener = listener;
    }
    
    /**
     * 绑定服务
     * @return 是否成功启动绑定
     */
    public boolean bindService() {
        if (isBound) {
            Log.w(TAG, "Service is already bound");
            return true;
        }
        
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(context, "com.anyun.h264.H264EncodeService"));
        
        boolean result = context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
        if (!result) {
            Log.e(TAG, "Failed to bind service");
        }
        return result;
    }
    
    /**
     * 解绑服务
     */
    public void unbindService() {
        if (isBound) {
            context.unbindService(connection);
            isBound = false;
            service = null;
            Log.d(TAG, "Service unbound");
        }
    }
    
    /**
     * 检查服务是否已绑定
     */
    public boolean isServiceBound() {
        return isBound && service != null;
    }
    
    /**
     * 控制H264编码
     * @param action 操作类型:0-开启h264文件写入,1-停止h264编码并停止写入文件,2-开启网络推送h264(不写入文件),3-停止h264编码并停止网络推送
     * @param jsonConfig JSON格式的配置参数,包含:ip(服务器IP)、port(服务器端口)、width(视频宽度)、height(视频高度)、framerate(帧率)、simPhone(SIM卡号)
     *                  示例:{"ip":"192.168.1.100","port":8888,"width":640,"height":480,"framerate":25,"simPhone":"013120122580"}
     *                  如果action为1或3(停止操作),此参数可为null
     * @return 0-成功,1-失败
     */
    public int controlEncode(int action, String jsonConfig) {
        if (!isServiceBound()) {
            Log.e(TAG, "Service is not bound");
            return 1; // 失败
        }
        
        try {
            int result = service.controlEncode(action, jsonConfig);
            Log.d(TAG, "controlEncode(" + action + ", " + jsonConfig + ") returned: " + result);
            return result;
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling controlEncode", e);
            return 1; // 失败
        }
    }
    
    /**
     * 控制H264编码(重载方法,兼容旧代码,使用null作为jsonConfig)
     * @param action 操作类型:0-开启h264文件写入,1-停止h264编码并停止写入文件,2-开启网络推送h264(不写入文件),3-停止h264编码并停止网络推送
     * @return 0-成功,1-失败
     * @deprecated 建议使用 controlEncode(int action, String jsonConfig) 方法,传入完整的配置参数
     */
    @Deprecated
    public int controlEncode(int action) {
        return controlEncode(action, null);
    }
    
    /**
     * 获取资源列表
     * @param startTime 开始时间(格式:YYMMDDHHmmss,例如:240101000000)
     * @param endTime 结束时间(格式:YYMMDDHHmmss,例如:240101235959)
     * @return 资源列表,如果失败返回null
     */
    public List<ResourceInfo> getResourceList(String startTime, String endTime) {
        if (!isServiceBound()) {
            Log.e(TAG, "Service is not bound");
            return null;
        }
        
        try {
            List<ResourceInfo> result = service.getResourceList(startTime, endTime);
            Log.d(TAG, "getResourceList returned " + (result != null ? result.size() : 0) + " resources");
            return result;
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling getResourceList", e);
            return null;
        }
    }
}