summaryrefslogtreecommitdiff
path: root/m3u8Parser.cpp
blob: 8d7382ba94b06a92a7a47eb02e257ca874f990c3 (plain)
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 "m3u8Parser.h"
#include <pcrecpp.h>

cM3u8Parser::cM3u8Parser()
{
	Init();
}
cM3u8Parser::cM3u8Parser(std::istream& m3u8)
{
	Init();
	Parse(m3u8);
}
void cM3u8Parser::Init()
{
	TargetDuration = -1;
	MediaSequence = -1;
	MasterPlaylist = false;
	AllowCache = true;
}


bool cM3u8Parser::Parse(std::istream& m3u8)
{
	bool ok = true;
	bool nextLineIsMedia = false;
	int lineNo = 0;

	// prepare regex
	pcrecpp::RE re("#(EXT[^:\\n]+)(?::[^\\n]+)");
	pcrecpp::RE reVal("(?::([^\\n]+))");

	std::string line;
	playListItem pItem;
	pItem.bandwidth = -1;
	pItem.file = "";
	pItem.length = -1;
	pItem.programId = -1;

	while (std::getline(m3u8, line)) {
		if(lineNo == 0 && "#EXTM3U" == line ) {
			// Invalid File
			ok = false;
			continue;
		}

		if( re.FullMatch(line) ) {
			string var;
			//string value;
			re.PartialMatch(line, &var);
			if("EXT-X-TARGETDURATION" == var) {
				int value;
				reVal.PartialMatch(line, &value);
				TargetDuration = value;
			} else if ("EXT-X-ALLOW-CACHE" == var) {
				string value;
				reVal.PartialMatch(line, &value);
				AllowCache = "YES" == value;
			} else if ("EXT-X-MEDIA-SEQUENCE" == var) {
				int value;
				reVal.PartialMatch(line, &value);
				MediaSequence = value;
			} else if ("EXT-X-STREAM-INF" == var) {
				MasterPlaylist = true;
				nextLineIsMedia = true;

				int bandw;
				pcrecpp::RE reBand("BANDWIDTH=(\\d+)");
				if(reBand.PartialMatch(line, &bandw)) {
					pItem.bandwidth = bandw;
				}

				int id;
				pcrecpp::RE reId("PROGRAM-ID=(\\d+)");
				if(reId.PartialMatch(line, &id)) {
					pItem.programId = id;
				}

			} else if ("EXTINF" == var) {
				MasterPlaylist = false;
				int value;
				pcrecpp::RE reInt("(?:#EXTINF:([\\d]+))");
				if( reInt.PartialMatch(line, &value)) {
					nextLineIsMedia = true;
					pItem.length = value;
				}
			}
		}
		// possible mediafile
		else {
			if(nextLineIsMedia) {
				nextLineIsMedia = false;
				pItem.file = line;
				pItem.size = 0;
				vPlaylistItems.push_back(pItem);
			}
		}
		lineNo++;
	}
	return ok;
}

/*
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4000000
session/731d4143-c05d-47ed-afa8-37913402630a/8/index.m3u8
*/

/*
#EXTM3U
#EXT-X-TARGETDURATION:3
#EXT-X-ALLOW-CACHE:NO
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:3, nodesc
00000.ts
#EXTINF:3, nodesc
00001.ts
...
#EXTINF:2, nodesc
01935.ts
#EXT-X-ENDLIST
*/