Skip to content

Commit 0e25c1f

Browse files
authored
v10.5.4
v10.5.4
2 parents 7867537 + d368327 commit 0e25c1f

File tree

6 files changed

+68
-33
lines changed

6 files changed

+68
-33
lines changed

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
Application for ESP32 / ESP32S3 with OV2640 / OV5640 camera to record JPEGs to SD card as AVI files and playback to browser as an MJPEG stream. The AVI format allows recordings to replay at correct frame rate on media players. If a microphone is installed then a WAV file is also created and stored in the AVI file.
55
The application supports:
6+
* [RTSP Server](#rtsp) stream Video, Audio and Subtitles
67
* [Motion detection by camera](#motion-detection-by-camera) or PIR / radar sensor
78
* Time lapse recording
89
* [Audio Recording](#audio-recording) from I2S or PDM microphones
@@ -27,8 +28,9 @@ The ESP32 cannot support all of the features as it will run out of heap space. F
2728
***This is a complex app and some users are raising issues when the app reports a warning, but this is the app notifying the user that there is an problem with their setup, which only the user can fix. Be aware that some clone boards have different specs to the original, eg PSRAM size. Please only raise issues for actual bugs (ERR messages, unhandled library error or crash). Thanks.
2829
To suggest an improvement or enhancement use Discussions.***
2930

30-
Changes up to version 10.5.3:
31+
Changes up to version 10.5.4:
3132
* Stream to [NVR](#stream-to-nvr) using integration to RTSPServer library contributed by [@rjsachse](https://github.com/rjsachse).
33+
* RTSP server now has multiple client support as well as user/pass authentication.
3234
* Frame resolution selection mismatch corrected due to [#10801](https://github.com/espressif/arduino-esp32/issues/10801) in arduino core v3.1.0
3335
* SD card 4 bit mode configurable (see `utilsFS.cpp`)
3436
* Shared I2C fixed following code changes in Arduino core v3.1.1
@@ -453,7 +455,7 @@ Streaming performance depends on quality of network connection, but can be incre
453455

454456
#### RTSP
455457

456-
This requires an additional library to be installed - see [RTSPServer](https://github.com/rjsachse/RTSPServer) library for details.
458+
This requires an additional library to be installed - see [RTSPServer](https://github.com/rjsachse/ESP32-RTSPServer) library for details. Must be version 1.3.1 or above
457459

458460
To integrate library with this app, set `#define INCLUDE_RTSP` to `true`.
459461

@@ -464,7 +466,14 @@ To enable RTSP, under **Edit Config** -> **Streaming** tab, select:
464466

465467
Then save and reboot.
466468

467-
To view the stream, connect to `rtsp://<camera_ip>:554` using app supporting RTSP.
469+
To view the stream, connect to `rtsp://<camera_ip>:<RTSPport>` using app supporting RTSP.
470+
471+
Or if authentication is enabled (username and password):
472+
`rtsp://<RTSPuser>:<RTSPpass>@<camera_ip>:<RTSPport>`
473+
474+
RTSP now supports multiple clients for multicast. You can also override this logic and enable multiple clients for all transports (TCP, UDP, Multicast) by commenting out //#define OVERRIDE_RTSP_SINGLE_CLIENT_MODE in rtsp.cpp.
475+
However, enabling multiple clients for all transports can slow the stream down and may cause issues, so use with care. It is better to leave it for only one client if using TCP or UDP unicast for best results. For more details,
476+
check out the README in the RTSPServer library.
468477

469478
#### HTTP
470479

appGlobals.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
#define INCLUDE_EXTHB false // externalHeartbeat.cpp (heartbeat to remote server)
6363
#define INCLUDE_PGRAM false // photogram.cpp (photogrammetry feature). Needs INCLUDE_PERIPH true
6464
#define INCLUDE_MCPWM false // mcpwm.cpp (BDC motor control). Needs INCLUDE_PERIPH true
65-
#define INCLUDE_RTSP false // rtsp.cpp (RTSP Streaming). Requires additional library: ESP32-RTSPServer
65+
#define INCLUDE_RTSP false // rtsp.cpp (RTSP Streaming). Requires additional library: Latest ESP32-RTSPServer (https://github.com/rjsachse/ESP32-RTSPServer)
6666
#define INCLUDE_DS18B20 false // if true, requires INCLUDE_PERIPH and additional libraries: OneWire and DallasTemperature
6767
#define INCLUDE_I2C false // periphsI2C.cpp (support for I2C peripherals)
6868

@@ -108,7 +108,7 @@
108108
#define DOT_MAX 50
109109
#define HOSTNAME_GRP 99
110110

111-
#define APP_VER "10.5.3"
111+
#define APP_VER "10.5.4"
112112

113113
#if defined(AUXILIARY)
114114
#define APP_NAME "ESP-CAM_AUX" // max 15 chars
@@ -151,7 +151,7 @@
151151
#define ISCAM // cam specific code in generics
152152

153153
// to determine if newer data files need to be loaded
154-
#define CFG_VER 25
154+
#define CFG_VER 26
155155

156156
#define AVI_EXT "avi"
157157
#define CSV_EXT "csv"
@@ -489,7 +489,10 @@ extern uint16_t rtpVideoPort;
489489
extern uint16_t rtpAudioPort;
490490
extern uint16_t rtpSubtitlesPort;
491491
extern char RTP_ip[];
492+
extern uint8_t rtspMaxClients;
492493
extern uint8_t rtpTTL;
494+
extern char RTSP_Name[];
495+
extern char RTSP_Pass[];
493496

494497
// task handling
495498
extern TaskHandle_t battHandle;

appSpecific.cpp

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -228,19 +228,6 @@ bool updateAppStatus(const char* variable, const char* value, bool fromUser) {
228228
else if (!strcmp(variable, "uartTxdPin")) uartTxdPin = intVal;
229229
else if (!strcmp(variable, "uartRxdPin")) uartRxdPin = intVal;
230230
#endif
231-
232-
#if INCLUDE_RTSP
233-
else if (!strcmp(variable, "rtsp0Video")) rtspVideo = streamVid = (bool)intVal;
234-
else if (!strcmp(variable, "rtsp1Audio")) rtspAudio = streamAud = (bool)intVal;
235-
else if (!strcmp(variable, "rtsp2Subtitles")) rtspSubtitles = streamSrt = (bool)intVal;
236-
else if (!strcmp(variable, "rtsp3Port")) rtspPort = intVal;
237-
else if (!strcmp(variable, "rtsp4VideoPort")) rtpVideoPort = intVal;
238-
else if (!strcmp(variable, "rtsp5AudioPort")) rtpAudioPort = intVal;
239-
else if (!strcmp(variable, "rtsp6SubtitlesPort")) rtpSubtitlesPort = intVal;
240-
else if (!strcmp(variable, "rtsp7Ip")) strncpy(RTP_ip, value, MAX_IP_LEN-1);
241-
else if (!strcmp(variable, "rtsp8TTL")) rtpTTL = intVal;
242-
#endif
243-
244231
#ifndef AUXILIARY
245232
// camera settings
246233
else if (!strcmp(variable, "xclkMhz")) xclkMhz = intVal;
@@ -991,13 +978,16 @@ relayMode~0~3~S:Manual:Night~How relay activated
991978
relaySwitch~0~3~C~Switch relay off / on
992979
I2Csda~-1~3~N~I2C SDA pin if unshared
993980
I2Cscl~-1~3~N~I2C SCL pin if unshared
994-
rtsp0Video~1~8~C~Enable RTSP Video
995-
rtsp1Audio~0~8~C~Enable RTSP Audio
996-
rtsp2Subtitles~1~8~C~Enable RTSP Subtitles
997-
rtsp3Port~554~8~N~RTSP ServerPort
998-
rtsp4VideoPort~5430~8~N~RTSP Video Port
999-
rtsp5AudioPort~5432~8~N~RTSP Audio Port
1000-
rtsp6SubtitlesPort~5434~8~N~RTSP Subtitles Port
1001-
rtsp7Ip~239.255.0.1~8~T~RTSP Multicast IP
1002-
rtsp8TTL~1~8~N~RTSP Multicast Time-to-Live
981+
RTSP_Name~~8~T~RTSP Auth Username
982+
RTSP_Pass~~8~T~RTSP Auth Password
983+
rtsp00Video~1~8~C~Enable RTSP Video
984+
rtsp01Audio~0~8~C~Enable RTSP Audio
985+
rtsp02Subtitles~1~8~C~Enable RTSP Subtitles
986+
rtsp03Port~554~8~N~RTSP ServerPort
987+
rtsp04VideoPort~5430~8~N~RTSP Video Port
988+
rtsp05AudioPort~5432~8~N~RTSP Audio Port
989+
rtsp06SubtitlesPort~5434~8~N~RTSP Subtitles Port
990+
rtsp07Ip~239.255.0.1~8~T~RTSP Multicast IP
991+
rtsp08MaxC~3~8~N~RTSP Multicast Max Connections
992+
rtsp09TTL~1~8~N~RTSP Multicast Time-to-Live
1003993
)~";

mjpeg2sd.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ static esp_err_t changeXCLK(camera_config_t config) {
841841
.speed_mode = LEDC_LOW_SPEED_MODE,
842842
.duty_resolution = LEDC_TIMER_1_BIT,
843843
.timer_num = config.ledc_timer,
844-
.freq_hz = config.xclk_freq_hz,
844+
.freq_hz = (uint32_t)config.xclk_freq_hz, // Fix arduino warning: narrowing conversion from 'int' to 'uint32_t'
845845
.clk_cfg = LEDC_AUTO_CLK
846846
};
847847
res = ledc_timer_config(&ledc_timer);

prefs.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ static bool savePrefs(bool retain = true) {
191191
#endif
192192
#if INCLUDE_MQTT
193193
prefs.putString("mqtt_user_Pass", mqtt_user_Pass);
194+
#endif
195+
#if INCLUDE_RTSP
196+
prefs.putString("RTSP_Pass", RTSP_Pass);
194197
#endif
195198
prefs.end();
196199
LOG_INF("Saved preferences");
@@ -221,6 +224,9 @@ static bool loadPrefs() {
221224
#endif
222225
#if INCLUDE_MQTT
223226
prefs.getString("mqtt_user_Pass", mqtt_user_Pass, MAX_PWD_LEN);
227+
#endif
228+
#if INCLUDE_RTSP
229+
prefs.getString("RTSP_Pass", RTSP_Pass, MAX_PWD_LEN);
224230
#endif
225231
prefs.end();
226232
return true;
@@ -314,7 +320,20 @@ void updateStatus(const char* variable, const char* _value, bool fromUser) {
314320
else if (!strcmp(variable, "mqtt_user_Pass") && value[0] != '*') strncpy(mqtt_user_Pass, value, MAX_PWD_LEN-1);
315321
else if (!strcmp(variable, "mqtt_topic_prefix")) strncpy(mqtt_topic_prefix, value, (FILE_NAME_LEN/2)-1);
316322
#endif
317-
323+
#if INCLUDE_RTSP
324+
else if (!strcmp(variable, "RTSP_Name")) strncpy(RTSP_Name, value, MAX_HOST_LEN-1);
325+
else if (!strcmp(variable, "RTSP_Pass") && value[0] != '*')strncpy(RTSP_Pass, value, MAX_PWD_LEN-1);
326+
else if (!strcmp(variable, "rtsp00Video")) rtspVideo = streamVid = (bool)intVal;
327+
else if (!strcmp(variable, "rtsp01Audio")) rtspAudio = streamAud = (bool)intVal;
328+
else if (!strcmp(variable, "rtsp02Subtitles")) rtspSubtitles = streamSrt = (bool)intVal;
329+
else if (!strcmp(variable, "rtsp03Port")) rtspPort = intVal;
330+
else if (!strcmp(variable, "rtsp04VideoPort")) rtpVideoPort = intVal;
331+
else if (!strcmp(variable, "rtsp05AudioPort")) rtpAudioPort = intVal;
332+
else if (!strcmp(variable, "rtsp06SubtitlesPort")) rtpSubtitlesPort = intVal;
333+
else if (!strcmp(variable, "rtsp07Ip")) strncpy(RTP_ip, value, MAX_IP_LEN-1);
334+
else if (!strcmp(variable, "rtsp08MaxC")) rtspMaxClients = intVal;
335+
else if (!strcmp(variable, "rtsp09TTL")) rtpTTL = intVal;
336+
#endif
318337
// Other settings
319338
else if (!strcmp(variable, "clockUTC")) syncToBrowser((uint32_t)intVal);
320339
else if (!strcmp(variable, "timezone")) strncpy(timezone, value, FILE_NAME_LEN-1);
@@ -410,6 +429,9 @@ void buildJsonString(uint8_t filter) {
410429
#endif
411430
#if INCLUDE_MQTT
412431
p += sprintf(p, "\"mqtt_user_Pass\":\"%.*s\",", strlen(mqtt_user_Pass), FILLSTAR);
432+
#endif
433+
#if INCLUDE_RTSP
434+
p += sprintf(p, "\"RTSP_Pass\":\"%.*s\",", strlen(RTSP_Pass), FILLSTAR);
413435
#endif
414436
}
415437
} else {

rtsp.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,22 @@
2828

2929
RTSPServer rtspServer;
3030

31+
//Comment out to enable multiple clients for all transports (TCP, UDP, Multicast)
32+
//#define OVERRIDE_RTSP_SINGLE_CLIENT_MODE
33+
3134
bool rtspVideo;
3235
bool rtspAudio;
3336
bool rtspSubtitles;
3437
int rtspPort;
3538
uint16_t rtpVideoPort;
3639
uint16_t rtpAudioPort;
3740
uint16_t rtpSubtitlesPort;
38-
char RTP_ip [MAX_IP_LEN];
41+
char RTP_ip[MAX_IP_LEN];
42+
uint8_t rtspMaxClients;
3943
uint8_t rtpTTL;
44+
char RTSP_Name[MAX_HOST_LEN-1] = "";
45+
char RTSP_Pass[MAX_PWD_LEN-1] = "";
46+
bool useAuth;
4047

4148
IPAddress rtpIp;
4249
char transportStr[30]; // Adjust the size as needed
@@ -123,6 +130,7 @@ static void startRTSPSubtitles(void* arg) {
123130
}
124131

125132
void prepRTSP() {
133+
useAuth = rtspServer.setCredentials(RTSP_Name, RTSP_Pass); // Set RTSP authentication
126134
RTSPServer::TransportType transport = determineTransportType();
127135
rtpIp.fromString(RTP_ip);
128136
rtspServer.transport = transport;
@@ -134,16 +142,19 @@ void prepRTSP() {
134142
rtspServer.rtpAudioPort = rtpAudioPort;
135143
rtspServer.rtpSubtitlesPort = rtpSubtitlesPort;
136144
rtspServer.rtpIp = rtpIp;
145+
rtspServer.maxRTSPClients = rtspMaxClients;
137146
rtspServer.rtpTTL = rtpTTL;
138147

139148
if (transport != RTSPServer::NONE) {
140149
if (rtspServer.init()) {
141150
LOG_INF("RTSP server started successfully with transport%s", transportStr);
142-
LOG_INF("Connect to: rtsp://%s:%d", WiFi.localIP().toString().c_str(), rtspServer.rtspPort);
151+
useAuth ?
152+
LOG_INF("Connect to: rtsp://<username>:<password>@%s:%d (credentials not shown for security reasons)", WiFi.localIP().toString().c_str(), rtspServer.rtspPort) :
153+
LOG_INF("Connect to: rtsp://%s:%d", WiFi.localIP().toString().c_str(), rtspServer.rtspPort);
143154

144155
// start RTSP tasks, need bigger stack for video
145156
if (rtspVideo) xTaskCreate(sendRTSPVideo, "sendRTSPVideo", 1024 * 5, NULL, SUSTAIN_PRI, &sustainHandle[1]);
146-
if (rtspAudio) xTaskCreate(sendRTSPAudio, "sendRTSPAudio", 1024 * 4, NULL, SUSTAIN_PRI, &sustainHandle[2]);
157+
if (rtspAudio) xTaskCreate(sendRTSPAudio, "sendRTSPAudio", 1024 * 5, NULL, SUSTAIN_PRI, &sustainHandle[2]);
147158
if (rtspSubtitles) xTaskCreate(startRTSPSubtitles, "startRTSPSubtitles", 1024 * 1, NULL, SUSTAIN_PRI, &sustainHandle[3]);
148159
} else {
149160
LOG_ERR("Failed to start RTSP server");

0 commit comments

Comments
 (0)