1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "ezlive_config.h"
#include "srtserver.h"
#include "ringbuf.h"
#include "transcode_talker.h"
#include "s3_worker.h"
typedef struct {
RingBuffer *ringbuf;
TranscodeTalker transcode_talker;
} MainCtx;
void on_rtmp_start(void *ctx) {
MainCtx *main_ctx = ctx;
main_ctx->ringbuf = malloc(sizeof(RingBuffer));
RingBuffer_init(main_ctx->ringbuf, 4096);
RingBuffer *rb = main_ctx->ringbuf;
TranscodeTalker_new_stream(&main_ctx->transcode_talker, rb);
RingBuffer_write_char(rb, 'F');
RingBuffer_write_char(rb, 'L');
RingBuffer_write_char(rb, 'V');
RingBuffer_write_char(rb, 1);
RingBuffer_write_char(rb, 5);
RingBuffer_write_word32be(rb, 9);
RingBuffer_write_word32be(rb, 0);
}
void on_rtmp_stop(void *ctx) {
MainCtx *main_ctx = ctx;
RingBuffer_end(main_ctx->ringbuf);
}
void on_rtmp_video(void *ctx, int64_t timestamp, char *buf, size_t size) {
MainCtx *main_ctx = ctx;
RingBuffer *rb = main_ctx->ringbuf;
RingBuffer_write_char(rb, 9);
RingBuffer_write_word24be(rb, size);
RingBuffer_write_word24be(rb, timestamp);
RingBuffer_write_char(rb, timestamp >> 24);
RingBuffer_write_word24be(rb, 0);
RingBuffer_write(rb, (const uint8_t *)buf, size);
RingBuffer_write_word32be(rb, size + 11);
}
void on_rtmp_audio(void *ctx, int64_t timestamp, char *buf, size_t size) {
MainCtx *main_ctx = ctx;
RingBuffer *rb = main_ctx->ringbuf;
RingBuffer_write_char(rb, 8);
RingBuffer_write_word24be(rb, size);
RingBuffer_write_word24be(rb, timestamp);
RingBuffer_write_char(rb, timestamp >> 24);
RingBuffer_write_word24be(rb, 0);
RingBuffer_write(rb, (const uint8_t *)buf, size);
RingBuffer_write_word32be(rb, size + 11);
}
void on_srt_start(void *ctx) {
MainCtx *main_ctx = ctx;
main_ctx->ringbuf = malloc(sizeof(RingBuffer));
RingBuffer_init(main_ctx->ringbuf, 4096);
RingBuffer *rb = main_ctx->ringbuf;
TranscodeTalker_new_stream(&main_ctx->transcode_talker, rb);
}
void on_srt_stop(void *ctx) {
MainCtx *main_ctx = ctx;
RingBuffer_end(main_ctx->ringbuf);
}
void on_srt_data(void *ctx, char *buf, size_t size) {
MainCtx *main_ctx = ctx;
RingBuffer *rb = main_ctx->ringbuf;
RingBuffer_write(rb, (const uint8_t*)buf, size);
}
void cleantmpfile() {
#ifdef _WIN32
system("del tmp*");
#else
system("rm /tmp/ezlive*");
#endif
}
int main(int argc, char **argv) {
cleantmpfile();
ezlive_config = malloc(sizeof(EZLiveConfig));
EZLiveConfig_init(ezlive_config);
bool succ;
if (argc == 1) {
succ = EZLiveConfig_load(ezlive_config, "./config");
#if defined(_WIN32)
if (!succ) {
succ = EZLiveConfig_load(ezlive_config, "./config.txt");
}
#endif
if (!succ) {
fprintf(stderr, "Failed to load config.\n");
return -1;
}
} else if (argc == 2) {
if (!EZLiveConfig_load(ezlive_config, argv[1])) {
fprintf(stderr, "Failed to load config.\n");
return -1;
}
} else {
fprintf(stderr, "wrong args.\n");
exit(-1);
}
int ret;
if ((ret = EZLiveConfig_validate(ezlive_config)) < 0) {
fprintf(stderr, "ezlive config error: %d.\n", ret);
exit(-1);
}
srand((unsigned) time(NULL));
MainCtx main_ctx;
SrtCallbacks srt_cbs = {
.on_data = &on_srt_data,
.on_stop = &on_srt_stop,
.on_start = &on_srt_start,
};
TranscodeTalker_init(&main_ctx.transcode_talker);
s3_worker_init();
s3_worker_push(s3_clear_task());
pthread_t transmux_thread;
pthread_create(&transmux_thread, NULL, &TranscodeTalker_main, &main_ctx.transcode_talker);
pthread_t s3worker_thread;
pthread_create(&s3worker_thread, NULL, &s3_worker_main, NULL);
// start_rtmpserver(rtmp_cbs, &main_ctx);
start_srt_server(srt_cbs, &main_ctx);
return 0;
}
|