diff --git a/html/recordplaytest.js b/html/recordplaytest.js
index 8cb6ae1d0e..0d66c4d58b 100644
--- a/html/recordplaytest.js
+++ b/html/recordplaytest.js
@@ -316,13 +316,9 @@ $(document).ready(function() {
},
ondataopen: function(data) {
Janus.log("The DataChannel is available!");
- $('#waitingvideo').remove();
$('#videobox').append(
''
);
- if(spinner)
- spinner.stop();
- spinner = null;
},
ondata: function(data) {
Janus.debug("We got data from the DataChannel!", data);
diff --git a/plugins/janus_recordplay.c b/plugins/janus_recordplay.c
index 35474b5f7a..5b4f536242 100644
--- a/plugins/janus_recordplay.c
+++ b/plugins/janus_recordplay.c
@@ -261,7 +261,6 @@
#include
#include
-#include
#include
#include
#include
@@ -406,7 +405,7 @@ typedef struct janus_recordplay_recording {
char *vfmtp; /* Video fmtp, if any */
int video_pt; /* Payload types to use for audio when playing recordings */
char *drc_file; /* Data file name */
- gboolean textdata; /* Data format is text */
+ gboolean textdata; /* Whether data format is text */
char *offer; /* The SDP offer that will be sent to watchers */
gboolean e2ee; /* Whether media in the recording is encrypted, e.g., using Insertable Streams */
GList *viewers; /* List of users watching this recording */
@@ -498,8 +497,6 @@ void janus_recordplay_send_rtcp_feedback(janus_plugin_session *handle, int video
#define AUDIO_PT 111
#define VIDEO_PT 100
-#define UDPHDR_SIZE 8
-
/* Helper method to check which codec was used in a specific recording (and if it's end-to-end encrypted) */
static const char *janus_recordplay_parse_codec(const char *dir, const char *filename, char *fmtp, size_t fmtplen, gboolean *e2ee) {
if(dir == NULL || filename == NULL)
@@ -626,7 +623,7 @@ static const char *janus_recordplay_parse_codec(const char *dir, const char *fil
const char *c = json_string_value(codec);
if (data) {
/* Found! */
- c = !strcasecmp(c, "text")? "text" : "bin";
+ c = !strcasecmp(c, "text") ? "text" : "binary";
json_decref(info);
fclose(file);
return c;
@@ -2072,8 +2069,10 @@ void janus_recordplay_update_recordings_list(void) {
char *ext = strstr(rec->drc_file, ".mjr");
if(ext != NULL)
*ext = '\0';
- rec->textdata = !strcasecmp("text", janus_recordplay_parse_codec(recordings_path,
- rec->drc_file, NULL, sizeof(NULL), NULL));
+ const char *textcodec = janus_recordplay_parse_codec(recordings_path,
+ rec->drc_file, NULL, sizeof(NULL), NULL);
+ if (textcodec)
+ rec->textdata = !strcasecmp("text", textcodec);
}
rec->audio_pt = AUDIO_PT;
if(rec->acodec != JANUS_AUDIOCODEC_NONE) {
@@ -2261,7 +2260,7 @@ janus_recordplay_frame_packet *janus_recordplay_get_frames(const char *dir, cons
}
w_time = json_integer_value(created);
/* Summary */
- JANUS_LOG(LOG_VERB, "This is %s recording:\n", video ? "a video" : audio ? "an audio" : "a data");
+ JANUS_LOG(LOG_VERB, "This is %s recording:\n", video ? "a video" : (audio ? "an audio" : "a data"));
JANUS_LOG(LOG_VERB, " -- Codec: %s\n", c);
JANUS_LOG(LOG_VERB, " -- Created: %"SCNi64"\n", c_time);
JANUS_LOG(LOG_VERB, " -- Written: %"SCNi64"\n", w_time);
@@ -2431,6 +2430,8 @@ janus_recordplay_frame_packet *janus_recordplay_get_frames(const char *dir, cons
return list;
}
+#define ntohll(x) ((1==ntohl(1)) ? (x) : ((gint64)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
+
static void *janus_recordplay_playout_thread(void *sessiondata) {
janus_recordplay_session *session = (janus_recordplay_session *)sessiondata;
if(!session) {
@@ -2539,7 +2540,6 @@ static void *janus_recordplay_playout_thread(void *sessiondata) {
if(audio_pt == 0 || audio_pt == 8 || audio_pt == 9)
akhz = 8;
int vkhz = 90;
- int dhz = 1;
while(!g_atomic_int_get(&session->destroyed) && session->active
&& !g_atomic_int_get(&rec->destroyed) && (audio || video)) {
@@ -2680,10 +2680,24 @@ static void *janus_recordplay_playout_thread(void *sessiondata) {
if(data) {
if(data == session->dframes) {
/* First packet, send now */
- /* Data recording stores raw UDP packets */
- fseek(dfile, data->offset+UDPHDR_SIZE, SEEK_SET);
- bytes = fread(buffer, sizeof(char), data->len-UDPHDR_SIZE, dfile);
- if(bytes != data->len-UDPHDR_SIZE)
+ /* Data recording stores recording timestamp in first 8 bytes - it follows the frame ts monotonically.
+ invariant: when = data->ts + when(initial packet) */
+ gint64 when = 0;
+ int len = data->len;
+ int offset = data->offset;
+ fseek(dfile, data->offset, SEEK_SET);
+ bytes = fread(&when, sizeof(gint64), 1, dfile);
+ when = ntohll(when); // NOTE: not currently used - playback is interested in actual data packets.
+ offset += sizeof(gint64);
+ len -= sizeof(gint64);
+
+ /* Read data packet */
+ fseek(dfile, offset, SEEK_SET);
+ bytes = fread(buffer, sizeof(char), len, dfile);
+ JANUS_LOG(LOG_INFO, "Sending data packet at rtp_timestamp = %lu, timestamp = %lu, delta = %lu\n", (data->ts), when, when - data->ts);
+ fseek(dfile, offset, SEEK_SET);
+ bytes = fread(buffer, sizeof(char), len, dfile);
+ if(bytes != data->len)
JANUS_LOG(LOG_WARN, "Didn't manage to read all the bytes we needed (%d < %d)...\n", bytes, data->len);
/* Update payload type */
janus_plugin_data datapacket = {
@@ -2703,7 +2717,6 @@ static void *janus_recordplay_playout_thread(void *sessiondata) {
} else {
/* What's the timestamp skip from the previous packet? */
ts_diff = data->ts - data->prev->ts;
- ts_diff = (ts_diff)/dhz;
/* Check if it's time to send */
gettimeofday(&now, NULL);
d_s = now.tv_sec - dbefore.tv_sec;
@@ -2726,16 +2739,27 @@ static void *janus_recordplay_playout_thread(void *sessiondata) {
dbefore.tv_sec += ts_diff/1000000;
dbefore.tv_usec -= ts_diff/1000000;
}
- /* Send now */
- fseek(dfile, data->offset+UDPHDR_SIZE, SEEK_SET);
- bytes = fread(buffer, sizeof(char), data->len-UDPHDR_SIZE, dfile);
- if(bytes != data->len-UDPHDR_SIZE)
+ /* Send now */
+ gint64 when = 0;
+ int len = data->len;
+ int offset = data->offset;
+ fseek(dfile, data->offset, SEEK_SET);
+ bytes = fread(&when, sizeof(gint64), 1, dfile);
+ when = ntohll(when);
+ offset += sizeof(gint64);
+ len -= sizeof(gint64);
+
+ /* Read data packet */
+ fseek(dfile, offset, SEEK_SET);
+ bytes = fread(buffer, sizeof(char), len, dfile);
+ JANUS_LOG(LOG_VERB, "Sending data packet at timestamp = %lu, recorded timestamp = %lu\n", (data->ts), when);
+ if(bytes != len)
JANUS_LOG(LOG_WARN, "Didn't manage to read all the bytes we needed (%d < %d)...\n", bytes, data->len);
/* Update payload type */
janus_plugin_data datapacket = {
.label = NULL,
.protocol = NULL,
- .binary = rec->textdata? FALSE : TRUE,
+ .binary = rec->textdata ? FALSE : TRUE,
.buffer = (char *)buffer,
.length = bytes
};
diff --git a/plugins/janus_streaming.c b/plugins/janus_streaming.c
index 498a42a7b0..f5482e3c7a 100644
--- a/plugins/janus_streaming.c
+++ b/plugins/janus_streaming.c
@@ -4000,7 +4000,7 @@ static json_t *janus_streaming_process_synchronous_request(janus_streaming_sessi
}
if(data) {
const char *datafile = json_string_value(data);
- drc = janus_recorder_create(NULL, source->textdata ? "text" : "bin", (char *)datafile);
+ drc = janus_recorder_create(NULL, "text", (char *)datafile);
if(drc == NULL) {
if(arc != NULL) {
janus_recorder_close(arc);