这是一个用于管理RTSP视频流拉取结果的HTTP服务器,提供查询和删除视频文件的功能。
cd /Users/wenhongquan/CLionProjects/jtjai_media
cmake --build cmake-build-debug --target jtjai_http_server
# 使用默认参数(输出目录:./output,端口:8080)
./cmake-build-debug/jtjai_http_server
# 指定输出目录
./cmake-build-debug/jtjai_http_server ./output
# 指定输出目录和端口
./cmake-build-debug/jtjai_http_server ./output 8080
./output
)8080
)请求
GET /api/timestamps
响应示例
{
"count": 3,
"timestamps": [
{
"timestamp": "20251010_163200",
"video_count": 2,
"total_size": 8385920
},
{
"timestamp": "20251010_163100",
"video_count": 2,
"total_size": 8385920
},
{
"timestamp": "20251010_163000",
"video_count": 2,
"total_size": 8385920
}
]
}
字段说明
count
: 时间戳目录总数timestamp
: 时间戳目录名称video_count
: 该目录下的视频数量total_size
: 该目录下所有视频的总大小(字节)请求
GET /api/videos
响应示例
{
"count": 6,
"videos": [
{
"filename": "test_stream1.mp4",
"full_path": "./output/20251010_163000/test_stream1.mp4",
"timestamp_dir": "20251010_163000",
"file_size": 1027405,
"created_time": "2025-10-10 16:30:26",
"stream_index": "1"
},
{
"filename": "test_stream2.mp4",
"full_path": "./output/20251010_163000/test_stream2.mp4",
"timestamp_dir": "20251010_163000",
"file_size": 7358515,
"created_time": "2025-10-10 16:30:26",
"stream_index": "2"
}
]
}
字段说明
filename
: 文件名full_path
: 完整路径timestamp_dir
: 所属时间戳目录file_size
: 文件大小(字节)created_time
: 创建时间stream_index
: 流索引(从文件名提取)请求
GET /api/videos?timestamp=20251010_163000
或者
GET /api/videos/20251010_163000
响应示例
{
"timestamp": "20251010_163000",
"count": 2,
"videos": [
{
"filename": "test_stream1.mp4",
"full_path": "./output/20251010_163000/test_stream1.mp4",
"timestamp_dir": "20251010_163000",
"file_size": 1027405,
"created_time": "2025-10-10 16:30:26",
"stream_index": "1"
}
]
}
请求
DELETE /api/video?path=./output/20251010_163000/test_stream1.mp4
响应示例(成功)
{
"success": true,
"path": "./output/20251010_163000/test_stream1.mp4",
"message": "文件删除成功"
}
响应示例(失败)
{
"success": false,
"path": "./output/20251010_163000/test_stream1.mp4",
"message": "文件删除失败"
}
安全限制
请求
DELETE /api/timestamp/20251010_163000
响应示例(成功)
{
"success": true,
"timestamp": "20251010_163000",
"path": "./output/20251010_163000",
"message": "目录删除成功"
}
响应示例(失败)
{
"success": false,
"timestamp": "20251010_163000",
"path": "./output/20251010_163000",
"message": "目录删除失败"
}
注意
请求
GET /api/config
响应示例
{
"global_config": {
"total_poll_duration_seconds": 60,
"max_concurrent_streams": 2,
"output_directory": "./output",
"report_filename": "rtsp_report.json",
"connection_timeout_seconds": 3,
"read_timeout_seconds": 5,
"poll_cycles": 3,
"cycle_interval_seconds": 30
},
"streams": [
{
"rtsp_url": "rtsp://example.com/stream1",
"duration_seconds": 15,
"weight": 1.0,
"output_filename": "test_stream1.mp4"
},
{
"rtsp_url": "rtsp://example.com/stream2",
"duration_seconds": 20,
"weight": 1.5,
"output_filename": "test_stream2.mp4"
}
]
}
字段说明
total_poll_duration_seconds
: 每轮轮询的总时长(秒)max_concurrent_streams
: 最大并发流数output_directory
: 输出目录report_filename
: 报告文件名connection_timeout_seconds
: 连接超时(秒)read_timeout_seconds
: 读取超时(秒)poll_cycles
: 轮询次数(-1为无限循环)cycle_interval_seconds
: 轮询间隔(秒)请求
GET /api/config/global
响应示例
{
"total_poll_duration_seconds": 60,
"max_concurrent_streams": 2,
"output_directory": "./output",
"report_filename": "rtsp_report.json",
"connection_timeout_seconds": 3,
"read_timeout_seconds": 5,
"poll_cycles": 3,
"cycle_interval_seconds": 30
}
请求
PUT /api/config/global
Content-Type: application/json
请求体示例
{
"max_concurrent_streams": 3,
"poll_cycles": 5,
"cycle_interval_seconds": 45
}
响应示例(成功)
{
"success": true,
"message": "全局配置更新成功",
"updated_config": {
"total_poll_duration_seconds": 60,
"max_concurrent_streams": 3,
"output_directory": "./output",
"report_filename": "rtsp_report.json",
"connection_timeout_seconds": 3,
"read_timeout_seconds": 5,
"poll_cycles": 5,
"cycle_interval_seconds": 45
}
}
响应示例(失败)
{
"error": "Bad Request",
"message": "配置验证失败: max_concurrent_streams 必须大于 0"
}
请求
GET /api/config/streams
响应示例
{
"count": 2,
"streams": [
{
"index": 0,
"rtsp_url": "rtsp://example.com/stream1",
"duration_seconds": 15,
"weight": 1.0,
"output_filename": "test_stream1.mp4"
},
{
"index": 1,
"rtsp_url": "rtsp://example.com/stream2",
"duration_seconds": 20,
"weight": 1.5,
"output_filename": "test_stream2.mp4"
}
]
}
请求
POST /api/config/streams
Content-Type: application/json
请求体示例
{
"rtsp_url": "rtsp://example.com/new_stream",
"duration_seconds": 25,
"weight": 1.8,
"output_filename": "new_stream.mp4"
}
响应示例(成功)
{
"success": true,
"message": "流配置添加成功",
"stream_index": 2,
"added_stream": {
"rtsp_url": "rtsp://example.com/new_stream",
"duration_seconds": 25,
"weight": 1.8,
"output_filename": "new_stream.mp4"
}
}
请求
PUT /api/config/streams/{index}
Content-Type: application/json
路径参数
index
: 流索引(从0开始)请求体示例
{
"duration_seconds": 30,
"weight": 2.0
}
响应示例(成功)
{
"success": true,
"message": "流配置更新成功",
"stream_index": 0,
"updated_stream": {
"rtsp_url": "rtsp://example.com/stream1",
"duration_seconds": 30,
"weight": 2.0,
"output_filename": "test_stream1.mp4"
}
}
请求
DELETE /api/config/streams/{index}
路径参数
index
: 流索引(从0开始)响应示例(成功)
{
"success": true,
"message": "流配置删除成功",
"deleted_stream_index": 1
}
响应示例(失败)
{
"error": "Not Found",
"message": "无效的流索引: 5"
}
请求
POST /api/config/save
响应示例(成功)
{
"success": true,
"message": "配置保存成功",
"saved_to": "config.json"
}
请求
POST /api/config/reload
响应示例(成功)
{
"success": true,
"message": "配置重新加载成功",
"loaded_from": "config.json"
}
请求
GET /api/tasks
响应示例
{
"scheduler_running": true,
"total_tasks": 2,
"completed_tasks": 1,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 0.5,
"tasks": [
{
"stream_index": 0,
"rtsp_url": "rtsp://example.com/stream1",
"output_file": "./output/20251011_144708/test_stream1.mp4",
"status_code": 4,
"status_name": "完成",
"start_time": "2025-10-11 14:47:08",
"end_time": "2025-10-11 14:47:23",
"progress": 15,
"bytes_received": 1024000,
"frames_received": 375,
"error_message": ""
},
{
"stream_index": 1,
"rtsp_url": "rtsp://example.com/stream2",
"output_file": "./output/20251011_144708/test_stream2.mp4",
"status_code": 3,
"status_name": "录制中",
"start_time": "2025-10-11 14:47:08",
"end_time": "1970-01-01 08:00:00",
"progress": 20,
"bytes_received": 512000,
"frames_received": 150,
"error_message": ""
}
]
}
状态码说明
0
: 空闲1
: 连接中2
: 已连接3
: 录制中4
: 完成5
: 连接错误6
: 录制错误7
: 超时8
: 已取消9
: 流不可用请求
GET /api/tasks/status
响应示例
{
"scheduler_running": true,
"total_tasks": 2,
"completed_tasks": 2,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 1.0,
"tasks": [
{
"stream_index": 0,
"rtsp_url": "rtsp://example.com/stream1",
"output_file": "./output/20251011_144708/test_stream1.mp4",
"status_code": 4,
"status_name": "完成",
"start_time": "2025-10-11 14:47:08",
"end_time": "2025-10-11 14:47:23",
"progress": 15,
"bytes_received": 1024000,
"frames_received": 375,
"error_message": ""
},
{
"stream_index": 1,
"rtsp_url": "rtsp://example.com/stream2",
"output_file": "./output/20251011_144708/test_stream2.mp4",
"status_code": 4,
"status_name": "完成",
"start_time": "2025-10-11 14:47:08",
"end_time": "2025-10-11 14:47:28",
"progress": 20,
"bytes_received": 2048000,
"frames_received": 600,
"error_message": ""
}
]
}
说明
/api/tasks
的响应格式相同,但提供实时状态更新请求
GET /api/scheduler/status
响应示例
{
"is_running": true,
"start_time": "2025-10-11 14:47:08",
"end_time": "1970-01-01 08:00:00",
"total_tasks": 2,
"completed_tasks": 2,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 1.0
}
字段说明
is_running
: 调度器是否正在运行start_time
: 调度器启动时间end_time
: 调度器结束时间(未结束时为1970-01-01)completion_rate
: 完成率(0.0-1.0)请求
GET /api/scheduler/cycle
响应示例
{
"scheduler_running": true,
"cycle_info": {
"start_time": "2025-10-11 14:47:08",
"elapsed_seconds": 25,
"total_duration": 60,
"progress_percentage": 41.67
},
"scheduler_stats": {
"total_tasks": 2,
"completed_tasks": 1,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 0.5
},
"active_tasks": [
{
"stream_index": 1,
"status": 3,
"progress_seconds": 12,
"target_duration": 20
}
]
}
说明
active_tasks
: 当前正在执行的任务列表请求
POST /api/scheduler/start
响应示例(成功)
{
"success": true,
"message": "调度器启动成功",
"is_running": true
}
响应示例(已在运行)
{
"error": "Conflict",
"message": "调度器已经在运行中"
}
请求
POST /api/scheduler/stop
响应示例(成功)
{
"success": true,
"message": "调度器停止成功",
"is_running": false
}
所有错误响应都遵循以下格式:
{
"error": "错误类型",
"message": "详细错误信息"
}
400 Bad Request
: 请求参数错误403 Forbidden
: 无权访问或删除404 Not Found
: 请求的资源不存在500 Internal Server Error
: 服务器内部错误curl http://localhost:8080/api/timestamps
curl http://localhost:8080/api/videos
curl http://localhost:8080/api/videos/20251010_163000
curl -X DELETE "http://localhost:8080/api/video?path=./output/20251010_163000/test_stream1.mp4"
curl -X DELETE http://localhost:8080/api/timestamp/20251010_163000
获取完整配置
curl http://localhost:8080/api/config
获取全局配置
curl http://localhost:8080/api/config/global
更新全局配置
curl -X PUT -H "Content-Type: application/json" -d '{
"max_concurrent_streams": 3,
"poll_cycles": 5
}' http://localhost:8080/api/config/global
获取流配置列表
curl http://localhost:8080/api/config/streams
添加新的流配置
curl -X POST -H "Content-Type: application/json" -d '{
"rtsp_url": "rtsp://example.com/new_stream",
"duration_seconds": 25,
"weight": 1.8,
"output_filename": "new_stream.mp4"
}' http://localhost:8080/api/config/streams
更新流配置
curl -X PUT -H "Content-Type: application/json" -d '{
"duration_seconds": 30,
"weight": 2.0
}' http://localhost:8080/api/config/streams/0
删除流配置
curl -X DELETE http://localhost:8080/api/config/streams/1
保存配置
curl -X POST http://localhost:8080/api/config/save
重新加载配置
curl -X POST http://localhost:8080/api/config/reload
获取任务列表
curl http://localhost:8080/api/tasks
获取实时任务状态
curl http://localhost:8080/api/tasks/status
获取调度器状态
curl http://localhost:8080/api/scheduler/status
获取当前周期状态
curl http://localhost:8080/api/scheduler/cycle
启动调度器
curl -X POST http://localhost:8080/api/scheduler/start
停止调度器
curl -X POST http://localhost:8080/api/scheduler/stop
// 列出所有视频
fetch('http://localhost:8080/api/videos')
.then(response => response.json())
.then(data => console.log(data));
// 删除视频
fetch('http://localhost:8080/api/video?path=./output/20251010_163000/test_stream1.mp4', {
method: 'DELETE'
})
.then(response => response.json())
.then(data => console.log(data));
// 获取配置
fetch('http://localhost:8080/api/config')
.then(response => response.json())
.then(data => console.log(data));
// 更新全局配置
fetch('http://localhost:8080/api/config/global', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
max_concurrent_streams: 3,
poll_cycles: 5
})
})
.then(response => response.json())
.then(data => console.log(data));
// 添加新流配置
fetch('http://localhost:8080/api/config/streams', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
rtsp_url: 'rtsp://example.com/stream',
duration_seconds: 30,
weight: 2.0,
output_filename: 'new_stream.mp4'
})
})
.then(response => response.json())
.then(data => console.log(data));
// 获取任务列表
fetch('http://localhost:8080/api/tasks')
.then(response => response.json())
.then(data => console.log(data));
// 获取实时任务状态
fetch('http://localhost:8080/api/tasks/status')
.then(response => response.json())
.then(data => console.log(data));
// 获取调度器状态
fetch('http://localhost:8080/api/scheduler/status')
.then(response => response.json())
.then(data => console.log(data));
// 启动调度器
fetch('http://localhost:8080/api/scheduler/start', {
method: 'POST'
})
.then(response => response.json())
.then(data => console.log(data));
// 停止调度器
fetch('http://localhost:8080/api/scheduler/stop', {
method: 'POST'
})
.then(response => response.json())
.then(data => console.log(data));
import requests
import json
# 列出所有视频
response = requests.get('http://localhost:8080/api/videos')
print(response.json())
# 删除视频
response = requests.delete('http://localhost:8080/api/video',
params={'path': './output/20251010_163000/test_stream1.mp4'})
print(response.json())
# 获取配置
response = requests.get('http://localhost:8080/api/config')
print(response.json())
# 更新全局配置
config_update = {
'max_concurrent_streams': 3,
'poll_cycles': 5
}
response = requests.put('http://localhost:8080/api/config/global',
json=config_update)
print(response.json())
# 添加新流配置
new_stream = {
'rtsp_url': 'rtsp://example.com/stream',
'duration_seconds': 30,
'weight': 2.0,
'output_filename': 'new_stream.mp4'
}
response = requests.post('http://localhost:8080/api/config/streams',
json=new_stream)
print(response.json())
# 更新流配置
stream_update = {
'duration_seconds': 25,
'weight': 1.8
}
response = requests.put('http://localhost:8080/api/config/streams/0',
json=stream_update)
print(response.json())
# 删除流配置
response = requests.delete('http://localhost:8080/api/config/streams/1')
print(response.json())
# 保存配置
response = requests.post('http://localhost:8080/api/config/save')
print(response.json())
# 获取任务列表
response = requests.get('http://localhost:8080/api/tasks')
print(response.json())
# 获取实时任务状态
response = requests.get('http://localhost:8080/api/tasks/status')
print(response.json())
# 获取调度器状态
response = requests.get('http://localhost:8080/api/scheduler/status')
print(response.json())
# 获取当前周期状态
response = requests.get('http://localhost:8080/api/scheduler/cycle')
print(response.json())
# 启动调度器
response = requests.post('http://localhost:8080/api/scheduler/start')
print(response.json())
# 停止调度器
response = requests.post('http://localhost:8080/api/scheduler/stop')
print(response.json())
服务器支持跨域请求(CORS),可以从任何域的网页中调用API。
output/
├── 20251010_163000/ # 第1轮的输出
│ ├── test_stream1.mp4
│ ├── test_stream2.mp4
│ ├── rtsp_report.json
│ ├── report.txt
│ └── streams.csv
├── 20251010_163100/ # 第2轮的输出
│ ├── test_stream1.mp4
│ ├── test_stream2.mp4
│ ├── rtsp_report.json
│ ├── report.txt
│ └── streams.csv
└── 20251010_163200/ # 第3轮的输出
├── test_stream1.mp4
├── test_stream2.mp4
├── rtsp_report.json
├── report.txt
└── streams.csv
服务器会扫描输出目录下所有的时间戳子目录,并提供统一的查询和管理接口。
请求
GET /api/config
响应示例
{
"global_config": {
"total_poll_duration_seconds": 60,
"max_concurrent_streams": 2,
"output_directory": "./output",
"report_filename": "rtsp_report.json",
"connection_timeout_seconds": 10,
"read_timeout_seconds": 15,
"poll_cycles": -1,
"cycle_interval_seconds": 30
},
"streams": [
{
"rtsp_url": "rtsp://218.94.57.146:40007/rtp/44010200492000000074_34020000001320000001",
"duration_seconds": 15,
"weight": 1.0,
"output_filename": "test_stream1.mp4"
},
{
"rtsp_url": "rtsp://218.94.57.146:40007/rtp/44010200492000000164_34020000001320000001",
"duration_seconds": 20,
"weight": 1.5,
"output_filename": "test_stream2.mp4"
}
]
}
请求
PUT /api/config
Content-Type: application/json
{
"global_config": {
"total_poll_duration_seconds": 120,
"max_concurrent_streams": 3,
"output_directory": "./output",
"report_filename": "rtsp_report.json",
"connection_timeout_seconds": 15,
"read_timeout_seconds": 30,
"poll_cycles": 5,
"cycle_interval_seconds": 60
},
"streams": [
{
"rtsp_url": "rtsp://example.com/stream1",
"duration_seconds": 30,
"weight": 2.0,
"output_filename": "new_stream1.mp4"
}
]
}
响应示例(成功)
{
"success": true,
"message": "配置更新成功"
}
请求
GET /api/config/global
响应示例
{
"total_poll_duration_seconds": 60,
"max_concurrent_streams": 2,
"output_directory": "./output",
"report_filename": "rtsp_report.json",
"connection_timeout_seconds": 10,
"read_timeout_seconds": 15,
"poll_cycles": -1,
"cycle_interval_seconds": 30
}
请求
PUT /api/config/global
Content-Type: application/json
{
"total_poll_duration_seconds": 120,
"max_concurrent_streams": 3,
"poll_cycles": 5
}
响应示例(成功)
{
"success": true,
"message": "全局配置更新成功"
}
说明
请求
GET /api/config/streams
响应示例
{
"count": 2,
"streams": [
{
"index": 0,
"rtsp_url": "rtsp://218.94.57.146:40007/rtp/44010200492000000074_34020000001320000001",
"duration_seconds": 15,
"weight": 1.0,
"output_filename": "test_stream1.mp4"
},
{
"index": 1,
"rtsp_url": "rtsp://218.94.57.146:40007/rtp/44010200492000000164_34020000001320000001",
"duration_seconds": 20,
"weight": 1.5,
"output_filename": "test_stream2.mp4"
}
]
}
请求
POST /api/config/streams
Content-Type: application/json
{
"rtsp_url": "rtsp://example.com/new_stream",
"duration_seconds": 25,
"weight": 1.8,
"output_filename": "new_stream.mp4"
}
响应示例(成功)
{
"success": true,
"message": "流配置添加成功",
"index": 2
}
请求
PUT /api/config/streams/0
Content-Type: application/json
{
"duration_seconds": 30,
"weight": 2.0
}
响应示例(成功)
{
"success": true,
"message": "流配置更新成功",
"index": 0
}
说明
请求
DELETE /api/config/streams/1
响应示例(成功)
{
"success": true,
"message": "流配置删除成功",
"deleted_index": 1
}
注意
请求
POST /api/config/save
Content-Type: application/json
{
"file_path": "config.json" // 可选,默认使用原文件路径
}
响应示例(成功)
{
"success": true,
"message": "配置保存成功",
"file_path": "config.json"
}
请求
POST /api/config/reload
响应示例(成功)
{
"success": true,
"message": "配置重新加载成功",
"file_path": "config.json"
}
400 Bad Request
: 请求参数错误或配置验证失败404 Not Found
: 流配置索引不存在503 Service Unavailable
: 配置管理器未初始化500 Internal Server Error
: 服务器内部错误{
"error": "Bad Request",
"message": "流配置参数不完整或不合法"
}
请求
GET /api/tasks
响应示例
{
"count": 2,
"tasks": [
{
"task_id": 0,
"stream_index": 0,
"rtsp_url": "rtsp://218.94.57.146:40007/rtp/44010200492000000074_34020000001320000001",
"output_file": "./output/test_stream1.mp4",
"duration_seconds": 15,
"status": 4,
"status_text": "已完成",
"start_time": "2025-10-11 16:30:05",
"end_time": "2025-10-11 16:30:20",
"error_message": "",
"bytes_received": 2048576,
"frames_received": 450
},
{
"task_id": 1,
"stream_index": 1,
"rtsp_url": "rtsp://218.94.57.146:40007/rtp/44010200492000000164_34020000001320000001",
"output_file": "./output/test_stream2.mp4",
"duration_seconds": 20,
"status": 3,
"status_text": "录制中",
"start_time": "2025-10-11 16:30:10",
"end_time": "",
"error_message": "",
"bytes_received": 1024000,
"frames_received": 300
}
],
"schedule_info": "调度方案: 2个任务\n任务 0: 0秒开始, 持续 15秒\n任务 1: 5秒开始, 持续 20秒"
}
字段说明
task_id
: 任务IDstream_index
: 流索引status
: 任务状态码(0=等待中, 1=连接中, 2=已连接, 3=录制中, 4=已完成, 5=连接错误, 6=录制错误, 7=超时, 8=已取消, 9=流不可用)status_text
: 状态文本描述请求
GET /api/tasks/status
响应示例
{
"scheduler_running": true,
"total_tasks": 2,
"completed_tasks": 1,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 0.5,
"tasks": [
{
"task_id": 0,
"stream_index": 0,
"status": 4,
"status_text": "已完成",
"progress": 15,
"bytes_received": 2048576,
"frames_received": 450,
"error_message": ""
},
{
"task_id": 1,
"stream_index": 1,
"status": 3,
"status_text": "录制中",
"progress": 12,
"bytes_received": 1536000,
"frames_received": 360,
"error_message": ""
}
]
}
说明
progress
: 当前任务的进度(秒)请求
GET /api/scheduler/status
响应示例
{
"is_running": true,
"total_tasks": 2,
"completed_tasks": 1,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 0.5,
"start_time": "2025-10-11 16:30:00",
"end_time": ""
}
请求
GET /api/scheduler/cycle
响应示例
{
"is_running": true,
"current_cycle": 1,
"cycle_progress": {
"elapsed_seconds": 25,
"total_seconds": 60,
"progress_percentage": 41.67
},
"scheduler_stats": {
"total_tasks": 2,
"completed_tasks": 1,
"failed_tasks": 0,
"cancelled_tasks": 0,
"max_concurrent_used": 2,
"completion_rate": 0.5
},
"active_tasks": [
{
"stream_index": 1,
"status": 3,
"progress_seconds": 12,
"target_duration": 20
}
]
}
说明
active_tasks
: 当前正在执行的任务列表请求
POST /api/scheduler/start
响应示例(成功)
{
"success": true,
"message": "调度器启动成功",
"is_running": true
}
响应示例(已在运行)
{
"error": "Conflict",
"message": "调度器已经在运行中"
}
请求
POST /api/scheduler/stop
响应示例(成功)
{
"success": true,
"message": "调度器停止成功",
"is_running": false
}