-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathicecast.c
123 lines (93 loc) · 3.16 KB
/
icecast.c
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
#include "icecast.h"
#include "ID3.h"
static HTTPSession *IcecastCreateSession(const char *Path, HTTPSession *Request, ListNode *Vars, int ICYInterval)
{
HTTPSession *Session;
char *Tempstr=NULL;
Session=HTTPSessionResponse(Request);
Session->ResponseCode=CopyStr(Session->ResponseCode,"200 OK");
Session->ContentType=CopyStr(Session->ContentType,GetVar(Vars,"ContentType"));
Session->LastModified=atoi(GetVar(Vars,"MTime-secs"));
Session->ContentSize=atoi(GetVar(Vars,"FileSize"));
Session->Flags |= SESSION_ICECAST;
Session->Protocol=CopyStr(Session->Protocol,"ICY");
Tempstr=FormatStr(Tempstr,"%d",ICYInterval);
SetVar(Session->Headers,"icy-metaint",Tempstr);
Destroy(Tempstr);
return(Session);
}
static void IcecastSendMessage(STREAM *Output, const char *ICYMessage)
{
uint8_t len;
char *Tempstr=NULL;
len=StrLen(ICYMessage);
if (len > 0) len=(len / 16) + 1;
Tempstr=SetStrLen(Tempstr,len * 16);
memset(Tempstr,0,len * 16);
strcpy(Tempstr,ICYMessage);
STREAMWriteBytes(Output,(char *) &len,1);
STREAMWriteBytes(Output,Tempstr,len * 16);
Destroy(Tempstr);
}
static void IcecastSendData(STREAM *Input, STREAM *Output, int ICYInterval)
{
char *ICYMessage=NULL, *Tempstr=NULL;
int BuffSize=4096, BytesRead=0, len, result;
ListNode *Vars;
Vars=ListCreate();
SetVar(Vars, "Title",GetBasename(Input->Path));
MediaReadDetails(Input,Vars);
ICYMessage=SubstituteVarsInString(ICYMessage,"StreamTitle='$(Title)'; StreamArtist='$(Artist)';",Vars,0);
LogToFile(Settings.LogPath,"Open: %s, message: %s",Input->Path,ICYMessage);
Tempstr=SetStrLen(Tempstr,BuffSize);
while (TRUE)
{
len=ICYInterval-BytesRead;
if (len > BuffSize) len=BuffSize;
result=STREAMReadBytes(Input,Tempstr,len);
if (result==EOF) break;
BytesRead+=result;
STREAMWriteBytes(Output,Tempstr,result);
if (BytesRead==ICYInterval)
{
LogToFile(Settings.LogPath,"SEND ICY: %s",ICYMessage);
BytesRead=0;
IcecastSendMessage(Output, ICYMessage);
//Don't send it again.
ICYMessage=CopyStr(ICYMessage,"");
}
}
ListDestroy(Vars,Destroy);
Destroy(ICYMessage);
Destroy(Tempstr);
}
void IcecastHandleStream(STREAM *Output, HTTPSession *Session, const char *SearchPath)
{
char *Tempstr=NULL;
HTTPSession *Response;
ListNode *Vars;
STREAM *S;
glob_t Glob;
int ICYInterval=4096000;
int i;
Vars=ListCreate();
SetVar(Vars,"ContentType","audio/mpeg");
Response=IcecastCreateSession("", Session, Vars, 0);
AlayaServerSendHeaders(Output, Response, FALSE);
STREAMFlush(Output);
Tempstr=MCopyStr(Tempstr,SearchPath,"/*",NULL);
glob(Tempstr,0,0,&Glob);
LogToFile(Settings.LogPath,"Stream from Dir: %s, %d files",SearchPath,Glob.gl_pathc);
for (i=0; i < Glob.gl_pathc; i++)
{
S=STREAMFileOpen(Glob.gl_pathv[i],SF_RDONLY);
if (S)
{
IcecastSendData(S, Output, 4096000);
STREAMClose(S);
}
}
globfree(&Glob);
Destroy(Tempstr);
ListDestroy(Vars,Destroy);
}