Skip to content

Commit 7a0a719

Browse files
committed
[FEAT] 添加音频处理工具模块,支持音频时长推断和学习参数计算
1 parent c4663ca commit 7a0a719

2 files changed

Lines changed: 162 additions & 9 deletions

File tree

ZJYMain/audio_utils.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2026/1/3
3+
# @Author : Assistant
4+
# @Site :
5+
# @File : audio_utils.py
6+
# @Software: PyCharm
7+
"""
8+
音频处理工具模块
9+
提供音频时长推断和相关工具函数
10+
"""
11+
12+
import json
13+
import logging
14+
import random
15+
16+
logger = logging.getLogger(__name__)
17+
18+
19+
def infer_audio_duration(file_size_bytes):
20+
"""
21+
根据音频文件大小推断时长(秒)
22+
23+
规则:
24+
- 使用64kbps低码率计算,确保时长充足
25+
- 增加20%缓冲时间
26+
- 限制在30秒到3600秒之间
27+
28+
参数:
29+
file_size_bytes: 文件大小,单位字节
30+
31+
返回:
32+
估算的时长(秒)
33+
"""
34+
if file_size_bytes <= 0:
35+
return 30 # 最少30秒
36+
37+
# 使用64kbps码率计算(最低码率,得到最长时长)
38+
# 64 kbps = 8 KB/s
39+
size_kb = file_size_bytes / 1024
40+
bitrate_kb_s = 8 # KB/s
41+
42+
duration_seconds = size_kb / bitrate_kb_s
43+
44+
# 增加20%的缓冲时间,确保时长充足
45+
duration_seconds = duration_seconds * 1.2
46+
47+
# 限制范围:最少30秒,最多3600秒(1小时)
48+
duration_seconds = max(30, min(duration_seconds, 3600))
49+
50+
return int(duration_seconds)
51+
52+
53+
def time_to_seconds(time_str):
54+
"""
55+
将时间字符串转换为秒数
56+
57+
支持格式:
58+
- "MM:SS"
59+
- "HH:MM:SS"
60+
61+
参数:
62+
time_str: 时间字符串
63+
64+
返回:
65+
秒数
66+
"""
67+
if not time_str:
68+
return 0
69+
70+
parts = time_str.split(':')
71+
if len(parts) == 2: # MM:SS
72+
minutes, seconds = int(parts[0]), int(parts[1])
73+
return minutes * 60 + seconds
74+
elif len(parts) == 3: # HH:MM:SS
75+
hours, minutes, seconds = int(parts[0]), int(parts[1]), int(parts[2])
76+
return hours * 3600 + minutes * 60 + seconds
77+
else:
78+
return 0
79+
80+
81+
def seconds_to_time_str(seconds):
82+
"""
83+
将秒数转换为MM:SS格式的时间字符串
84+
85+
参数:
86+
seconds: 秒数
87+
88+
返回:
89+
MM:SS格式字符串
90+
"""
91+
minutes = seconds // 60
92+
seconds = seconds % 60
93+
return f"{minutes}:{seconds:02d}"
94+
95+
96+
def parse_audio_file_info(audio_info):
97+
"""
98+
解析音频信息,提取文件大小和URL
99+
100+
参数:
101+
audio_info: 音频信息字典
102+
103+
返回:
104+
dict: 包含file_size和file_url的字典
105+
"""
106+
try:
107+
file_url_data = json.loads(audio_info['fileUrl'])
108+
return {
109+
'file_size': file_url_data.get('size', 1093170),
110+
'file_url': file_url_data.get('url', ''),
111+
'md5': file_url_data.get('md5', '')
112+
}
113+
except Exception as e:
114+
logger.error(f"解析音频信息失败: {e}")
115+
return {
116+
'file_size': 1093170, # 默认值
117+
'file_url': '',
118+
'md5': ''
119+
}
120+
121+
122+
def calculate_audio_study_params(audio_info):
123+
"""
124+
计算音频学习参数
125+
126+
参数:
127+
audio_info: 音频信息字典
128+
129+
返回:
130+
dict: 包含学习所需的各项参数
131+
"""
132+
# 解析文件信息
133+
file_info = parse_audio_file_info(audio_info)
134+
file_size = file_info['file_size']
135+
136+
# 推断时长
137+
duration_seconds = infer_audio_duration(file_size)
138+
139+
# 计算学习时间(增加随机缓冲)
140+
study_time = duration_seconds + random.randint(12, 22)
141+
142+
# 转换为时间字符串
143+
audio_time = seconds_to_time_str(duration_seconds)
144+
145+
return {
146+
'duration_seconds': duration_seconds,
147+
'study_time': study_time,
148+
'audio_time': audio_time,
149+
'file_size': file_size,
150+
'file_url': file_info['file_url']
151+
}

ZJYMain/look_video.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from Crypto.Cipher import AES
1616
from Crypto.Hash import MD5
1717
from Crypto.Util.Padding import pad
18+
from ZJYMain.audio_utils import calculate_audio_study_params
1819

1920
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
2021
logger = logging.getLogger(__name__)
@@ -160,7 +161,7 @@ def study_record(session, info, class_id):
160161
file_type = info['fileType']
161162
course_id = info.get('id') or info.get('activityId')
162163
course_info_id = info['courseInfoId']
163-
file_url = json.loads(info['fileUrl'])['url']
164+
file_url = json.loads(info['fileUrl'])['url'] if info.get('fileUrl') else ''
164165
if file_type in ["img", "图文"]:
165166
resp_result = stu_process_cell_log(session, course_info_id, class_id, random.randint(12, 22), course_id, 1)
166167
sleep_randint = random.randint(5, 10)
@@ -173,14 +174,15 @@ def study_record(session, info, class_id):
173174
sleep_randint = random.randint(5, 10)
174175
logging.info('\t\t\t\t\t\t学习课件中... 课程: %s 延时: %s 结果: %s', name, sleep_randint, resp_result)
175176
time.sleep(sleep_randint)
176-
# elif file_type == "audio":
177-
# audio_time = content_audio(session, course_id, course_id)
178-
# audio_time_sec = time_to_seconds(audio_time)
179-
# resp_result = stu_process_cell_log(session, course_info_id, class_id, audio_time_sec, course_id, audio_time)
180-
# logging.info('\t\t\t\t\t\t学习课件中... 课程: %s 延时: %s 结果: %s', name, sleep_randint, resp_result)
181-
# time.sleep(sleep_randint)
177+
elif file_type == "audio":
178+
audio_params = calculate_audio_study_params(info)
179+
study_time = audio_params['study_time']
180+
duration_seconds = audio_params['duration_seconds']
181+
resp_result = stu_process_cell_log(session, course_info_id, class_id, study_time, course_id, duration_seconds)
182+
logging.info('\t\t\t\t\t\t学习课件中... 课程: %s 学习时长: %s秒 延时: %s 结果: %s', name, duration_seconds, sleep_randint, resp_result)
183+
time.sleep(sleep_randint)
182184
elif file_type == "video":
183-
video_time = get_video_time(session, file_url)['args']['duration']
185+
video_time = get_video_time(session, file_url)['args'].get('duration', '00:10')
184186
total_seconds = int(sum(float(x) * 60 ** i for i, x in enumerate(reversed(video_time.split(':')))))
185187
study_time = total_seconds + random.randint(12, 22)
186188
resp_result = stu_process_cell_log(session, course_info_id, class_id, study_time, course_id, total_seconds)
@@ -197,12 +199,12 @@ def process_standard_course(session, i):
197199
moduleList1 = get_process_list(session, i['courseId'], i['courseInfoId'], i['classId'], 0, 1)
198200

199201
for j in moduleList1:
200-
time.sleep(random.uniform(0.5, 1))
201202
if j['speed'] == 100:
202203
logging.info("\t%s 课程已刷进度 100", j['name'])
203204
continue
204205
logging.info("\t%s", j['name'])
205206
# 二级目录
207+
time.sleep(random.uniform(0.5, 1))
206208
moduleList2 = get_process_list(session, i['courseId'], i['courseInfoId'], i['classId'], j['id'], 2)
207209
for k in moduleList2:
208210
# time.sleep(random.uniform(0.5, 1))

0 commit comments

Comments
 (0)