硬汉嵌入式论坛

 找回密码
 立即注册
查看: 289|回复: 12
收起左侧

[STM32H7] 基于STM32H7和ESP32S3的网络收音机开发实战指南--前言&网络源分析与获取【1】

[复制链接]

3

主题

12

回帖

26

积分

新手上路

积分
26
发表于 2025-11-27 18:30:06 | 显示全部楼层 |阅读模式

版权声明
音频来源 央广网文化传媒有限公司 版权所有。写作本文时处于边摸索边开发中。若有参考网络资源,会贴上相关链接,感谢作者的开源精神。
本系列文档归笔者所有,未经授权,禁止转载。@2025~2035

设计目标
带领大家玩转一个网络项目。玩中学-学中玩。有需求或疑问,欢迎交流。想实时沟通可进QQ群交流 532183273

需要的技能/可学到的技能
计算机网络基础知识
数据结构与算法
单片机基础知识与应用
Python 、 C、汇编   编程技能
。。。//【考研408熟练那就理解很快了】

背景

想听广播,看到了央广网的网页,可以在线收听,手机电脑都可打开,也可下载云听app听,链接:https://www.cnr.cn/gbzb/
主页如下图
1.png

引出问题
这个播放过程是什么?如何使用ESP32S3获取链接呢?什么格式的音频?如何使用STM32H7解码,选软解还是硬解方案?怎么在mcu上实现同样的播放效果?


分析过程
通过chrome浏览器的F12开发者工具,选择network进行分析,当访问https://www.cnr.cn/gbzb/这个链接时,发生了很多事情,
通过对各个文件【css样式文件,js脚本,png/jpg/gif多种格式的各种控件图片,html网页等】的分析,笔者找到了最核心的各个电台的播放链接!!如下
2.png
这个json格式的内容,里面就包括了我们要的这22个在线电台的播放链接,这里使用在线格式化工具看下,就很清晰了,如下:
3.png
https://ngcdn001.cnr.cn/live/zgzs/index.m3u8?key=e377bfa0dbd6e3a68b355a5f878a5cf6&time=1764214994
看链接细节可知,不同电台的地址不一样,key不一样,但是timestamp是一样的,这个是央广的cdn服务器提供的授权key和时间戳,我们客户端再拿这2个参数构造请求链接。
这里使用python解析json,就能提取这个页面所有的电台信息和播放链接了。如下
4.png
这里给出文本格式的源码和结果
import requests,json

url = "https://apppc.cnr.cn/national"
rsp = requests.post(url, json={})#headers=headers,
_keytimestamp = rsp.text

keytimestamp = json.loads(_keytimestamp)
print(type(keytimestamp))#,keytimestamp)

if keytimestamp['code'] == "200":
    totalcount = keytimestamp['data']['totalcount']
    for index in range(totalcount):
        pictureurl = keytimestamp['data']['categories'][0]['detail'][index]['other_info6']
        name = keytimestamp['data']['categories'][0]['detail'][index]['name']
        requesturl = keytimestamp['data']['categories'][0]['detail'][index]['other_info11'][2]['url']
        print('%d->'%(index),requesturl)
        #print(name) #提取所有电台名
        #print(pictureurl)
        #print(keytimestamp['data']['categories'][0]['detail'])
运行结果
0-> https://ngcdn001.cnr.cn/live/zgz ... amp;time=1764221053  //请求的时间不一样,key和time是不一样的,沿用会给你返回一个报错的网页~~~
1-> https://ngcdn002.cnr.cn/live/jjz ... amp;time=1764221053
2-> https://ngcdn003.cnr.cn/live/yyz ... amp;time=1764221053
3-> https://ngcdn004.cnr.cn/live/dsz ... amp;time=1764221053
4-> https://ngcdn005.cnr.cn/live/zhz ... amp;time=1764221053
5-> https://ngcdn006.cnr.cn/live/szz ... amp;time=1764221053
6-> https://ngcdn007.cnr.cn/live/hxz ... amp;time=1764221053
7-> https://ngcdn009.cnr.cn/live/mzz ... amp;time=1764221053
8-> https://ngcdn010.cnr.cn/live/wyz ... amp;time=1764221053
9-> https://ngcdn011.cnr.cn/live/lnz ... amp;time=1764221053
10-> https://ngcdn012.cnr.cn/live/zyg ... amp;time=1764221053
11-> https://ngcdn014.cnr.cn/live/ylg ... amp;time=1764221053
12-> https://ngcdn013.cnr.cn/live/wyg ... amp;time=1764221053
13-> https://ngcdn008.cnr.cn/live/xgz ... amp;time=1764221053
14-> https://ngcdn016.cnr.cn/live/gsg ... amp;time=1764221053
15-> https://ngcdn017.cnr.cn/live/xcz ... amp;time=1764221053
16-> https://ngcdn025.cnr.cn/live/hyg ... amp;time=1764221053
17-> https://sk.cri.cn/905.m3u8?key=2 ... amp;time=1764221053
18-> https://sk.cri.cn/nhzs.m3u8?key= ... amp;time=1764221053
19-> https://sk.cri.cn/915.m3u8?key=c ... amp;time=1764221053
20-> https://sk.cri.cn/887.m3u8?key=0 ... amp;time=1764221053
21-> https://sk.cri.cn/am846.m3u8?key ... amp;time=1764221053



接下来的问题,如何构造请求拿到这些链接呢?我们观察浏览器的 Headers和Payload 即可得到答案。
5.png
使用的是http的post请求,注意,不是get,那么post请求的body是啥呢?这里笔者懒得截图Payload的内容,因为太简单,就是个空json --> {}
意味着,央广CDN不要你传啥参数给它,按照请求体里的json格式要求传个空json给它就行,这就是python代码里形参为json={}的原因,不传的话,CDN会返回一个错误,无法获取正确应答。

下个问题,index.m3u8是不是很熟悉??这就不是苹果出的HLS直播推流协议吗!!!接下来就简单了,也就是在线播放的时候,客户端一直请求 m3u8文件,获取里面的 ts文件链接,再解码音频,这个网络收音机不就完成了!!
6.png
关于 HLS协议, m3u8 文件 + ts 音视频文件 的详细讲解,笔者会放到后续的章节里进行详细介绍,当然,读者也可以去自行百度,都是公开的,很多人分享。
7.png
这里,浏览器每10s请求一次m3u8文件,拿到下一个音频片段的文件名,从而可以合成音频下载链接。里面几个文件,即对应了网络不佳时可以缓冲的时间,用户不会感觉到网络波动。
8.png
https://ngcdn001.cnr.cn/live/zgzs/index.m3u8?key=bb8deb992e5b415fbaafc28cb191b0f2&time=1764222596    使用http get请求,获取m3u8文件【一个灰常简单的文本文件】
https://ngcdn001.cnr.cn/live/zgzs/13420389.ts     使用http get请求,获取m3u8文件里提取的音频片段文件名
https://ngcdn001.cnr.cn/live/zgzs/13420390.ts     定时请求ts音频文件【文件可大了250KB左右,里面240KB左右是10s的压缩音频数据+ts复杂的文件结构
https://ngcdn001.cnr.cn/live/zgzs/13420391.ts
。。。
注意不同电台不一定都是10s,还有3s的【最后几个电台】,看CDN服务器如何设置

解决问题
根据上文的分析过程,这个完整的获取流程是这样的:
1.获取某个在线电台的播放链接 ,主要是为了拿到 key和timestamp ,注意cdn服务器给的timestamp会比当前时间慢几分钟,是正确的!!可以理解成直播流链接防盗链的鉴权机制的原因。细节不展开。后面可以一直用这个固定的时间戳值一直请求m3u8文件。
2.定时请求m3u8文件,拿到真正的ts音频文件的链接地址。
3.解析ts,提取压缩音频,解码并播放。

硬件实现方案
方案1:
        esp32s3_n16r8+idf+c/ esp32s3+arduino+ c++ 目前比较流行这种,立创开源很多这种网络收音机方案,但是笔者用于学习mcu目的,不采用这种方案。
方案2
         esp32s3_n16r8(flash:16MB,SRAM:8MB)+micropython+stm32h7,学习python和stm32h7的好方案。学习,不在乎这点成本,潜力无限。

方案3
         全志/瑞芯微/树莓派。那我还学什么?学如何熟练点击按钮吗?或者拿来学QT做个酷酷的界面学GUI【好想法】?



开发参考资源:
央广在线FM          https://www.cnr.cn/gbzb/
在线时间戳           https://www.beijing-time.org/shijianchuo/
json在线格式化     https://www.sojson.com/
chatGPT               https://chatgpt.com/
Python开发软件    Spyder

后续内容预告
HLS协议如何理解和解析?
ts文件如何提取里面的音频,是mp3格式,还是aac格式?如何解码对应格式?【这里提前透露,央视的是aac-lc音频压缩格式】
硬件设计方案的细节如何敲定,各芯片如何选型?
。。。

也许读者有大量疑问,且见下回分享。

注:由于涉及到太多细节,笔者不打算详细解释很多细节,涉及到太多基础技能和知识了,这种得出系列视频,才能事无巨细。



评分

参与人数 2金币 +110 收起 理由
xieyang__ + 10 赞一个!
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

3

主题

12

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 7 天前 | 显示全部楼层
综合效果播放演示视频链接:bilibili.com/video/BV113SgBbEDG/   原理图,各种源码等,在后续章节中陆续放在gitee上开源。
回复

使用道具 举报

3

主题

119

回帖

128

积分

初级会员

积分
128
发表于 7 天前 | 显示全部楼层
已收藏,怎么+关注啊老哥?
回复

使用道具 举报

0

主题

41

回帖

41

积分

新手上路

积分
41
发表于 7 天前 | 显示全部楼层
学习学习,期待
回复

使用道具 举报

7

主题

24

回帖

45

积分

新手上路

积分
45
发表于 7 天前 | 显示全部楼层
楼主讲解很详细,给力,感谢分享!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119671
QQ
发表于 7 天前 | 显示全部楼层
支持
回复

使用道具 举报

3

主题

50

回帖

59

积分

初级会员

积分
59
发表于 7 天前 | 显示全部楼层
说到这个,理论上stm32h7能不能用软模拟的方法做到接收广播呢,不使用网络的情况下,就好像以前的那些老古董收音机,把天线拉出来,然后调频就可以收到一些广播频道了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119671
QQ
发表于 7 天前 | 显示全部楼层
spi-sd 发表于 2025-11-28 10:51
说到这个,理论上stm32h7能不能用软模拟的方法做到接收广播呢,不使用网络的情况下,就好像以前的那些老古 ...

可以搞低配版无线电,就是范围有限

单片机实现低配版全功能软件无线电,范围0.5-30 MHz,支持SSB、AM、FM和CW
https://forum.anfulai.cn/forum.p ... 2857&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

3

主题

12

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 7 天前 | 显示全部楼层
spi-sd 发表于 2025-11-28 10:51
说到这个,理论上stm32h7能不能用软模拟的方法做到接收广播呢,不使用网络的情况下,就好像以前的那些老古 ...

可以,俄罗斯爱好者开源的著名 孔雀石SDR 软件无线电,其主控就是stm32h743 。【软件不开源,需要序列号,硬件原理图开源,立创广场曾经有原理图】
参考链接:https://baijiahao.baidu.com/s?id ... r=spider&for=pc
    https://bbs.kanxue.com/thread-265660-2.htm

另一种常见方案是fgpa做主控,性能大大提升,链接:
    https://oshwhub.com/GaAs/qian-zhao-yi-tai-wang-pluto-sdr-
回复

使用道具 举报

3

主题

50

回帖

59

积分

初级会员

积分
59
发表于 7 天前 | 显示全部楼层
eric2013 发表于 2025-11-28 10:57
可以搞低配版无线电,就是范围有限

单片机实现低配版全功能软件无线电,范围0.5-30 MHz,支持SSB、AM ...

这个看起来很复杂啊,我的设想是根据国内的情况,固定几个调频的电台就可以了,通过按键切换,这样都不需要屏幕显示,这样应该会简单很多了吧?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119671
QQ
发表于 7 天前 | 显示全部楼层
spi-sd 发表于 2025-11-28 11:09
这个看起来很复杂啊,我的设想是根据国内的情况,固定几个调频的电台就可以了,通过按键切换,这样都不需 ...

那就是搞个收音机模块吧,现在我们开发板上面还有。这种的可玩性不高。
回复

使用道具 举报

3

主题

50

回帖

59

积分

初级会员

积分
59
发表于 7 天前 | 显示全部楼层
eric2013 发表于 2025-11-28 11:28
那就是搞个收音机模块吧,现在我们开发板上面还有。这种的可玩性不高。

这样的比较适合我们这些新手学习啊,不用太复杂,连个接口传输接收的数据给个喇叭播放就可以了
回复

使用道具 举报

12

主题

172

回帖

208

积分

高级会员

积分
208
发表于 4 小时前 | 显示全部楼层
楼主的QQ群号搜了下怎么没有呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-12-5 12:05 , Processed in 0.062726 second(s), 33 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表