Skip to content

Commit f87614e

Browse files
committed
* v0.3.9
1 parent fa30ebf commit f87614e

File tree

15 files changed

+369
-245
lines changed

15 files changed

+369
-245
lines changed

example/streamedian.js

Lines changed: 252 additions & 150 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/streamedian.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "streamedian",
3-
"version": "0.3.8",
3+
"version": "0.3.9",
44
"description": "HTML5 MSE RTSP player over websockets",
55
"license": "Apache2",
66
"author": "Streamedian <streamedian.player@gmail.com> (http://streamedian.com/)",

src/client/rtsp/client.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ class AuthError extends Error {
9292
}
9393
}
9494

95+
export class RTSPError extends Error {
96+
constructor(data) {
97+
super(data.msg);
98+
this.data = data;
99+
}
100+
}
101+
95102
export class RTSPClientSM extends StateMachine {
96103
static get USER_AGENT() {return 'SFRtsp 0.3';}
97104
static get STATE_INITIAL() {return 1 << 0;}

src/client/rtsp/stream.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {getTagged} from '../../deps/bp_logger.js';
22

33
import {RTSPClientSM as RTSPClient} from './client.js';
44
import {Url} from '../../core/util/url.js';
5+
import {RTSPError} from "./client";
56

67
const LOG_TAG = "rtsp:stream";
78
const Log = getTagged(LOG_TAG);

src/core/base_client.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,14 @@ export class BaseClient {
103103
onDisconnected() {
104104
this.connected = false;
105105
}
106+
107+
queryCredentials() {
108+
return Promise.resolve();
109+
}
110+
111+
setCredentials(user, password) {
112+
this.endpoint.user = user;
113+
this.endpoint.pass = password;
114+
this.endpoint.auth = `${user}:${password}`;
115+
}
106116
}

src/core/elementary/NALU.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export class NALU {
77
static get SEI() {return 6;}
88
static get SPS() {return 7;}
99
static get PPS() {return 8;}
10+
static get STAP_A() {return 24;}
11+
static get STAP_B() {return 25;}
1012
static get FU_A() {return 28;}
1113
static get FU_B() {return 29;}
1214

src/core/elementary/NALUAsm.js

Lines changed: 77 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5,101 +5,99 @@ import {NALU} from './NALU.js';
55
export class NALUAsm {
66

77
constructor() {
8-
this.nalu_l = null;
9-
this.nalu_t = null;
10-
this.dts_l = 0;
8+
this.fragmented_nalu = null;
119
}
1210

13-
shiftTemp(val) {
14-
let ret;
15-
if (this.nalu_t != null) {
16-
ret = this.nalu_t;
17-
this.nalu_t = val;
18-
} else {
19-
ret = val;
11+
12+
static parseNALHeader(hdr) {
13+
return {
14+
nri: hdr & 0x60,
15+
type: hdr & 0x1F
2016
}
21-
return ret ? [ret] : null;
2217
}
2318

24-
onNALUFragment(rawData, dts, pts) {
19+
parseSingleNALUPacket(rawData, header, dts, pts) {
20+
return new NALU(header.type, header.nri, rawData.subarray(0), dts, pts);
21+
}
2522

23+
parseAggregationPacket(rawData, header, dts, pts) {
2624
let data = new DataView(rawData.buffer, rawData.byteOffset, rawData.byteLength);
25+
let nal_start_idx = 0;
26+
let don = null;
27+
if (NALU.STAP_B === header.type) {
28+
don = data.getUint16(nal_start_idx);
29+
nal_start_idx += 2;
30+
}
31+
let ret = [];
32+
while (nal_start_idx < data.byteLength) {
33+
let size = data.getUint16(nal_start_idx);
34+
nal_start_idx += 2;
35+
let header = NALUAsm.parseNALHeader(data.getInt8(nal_start_idx));
36+
nal_start_idx++;
37+
let nalu = this.parseSingleNALUPacket(rawData.subarray(nal_start_idx, nal_start_idx+size), header, dts, pts);
38+
if (nalu !== null) {
39+
ret.push(nalu);
40+
}
41+
nal_start_idx+=size;
42+
}
43+
return ret;
44+
}
2745

28-
let nalhdr = data.getUint8(0);
46+
parseFragmentationUnit(rawData, header, dts, pts) {
47+
let data = new DataView(rawData.buffer, rawData.byteOffset, rawData.byteLength);
48+
let nal_start_idx = 0;
49+
let fu_header = data.getUint8(nal_start_idx);
50+
let is_start = (fu_header & 0x80) >>> 7;
51+
let is_end = (fu_header & 0x40) >>> 6;
52+
let payload_type = fu_header & 0x1F;
53+
let ret = null;
2954

30-
let nri = nalhdr & 0x60;
31-
let naltype = nalhdr & 0x1F;
55+
nal_start_idx++;
56+
let don = 0;
57+
if (NALU.FU_B === header.type) {
58+
don = data.getUint16(nal_start_idx);
59+
nal_start_idx += 2;
60+
}
3261

33-
let nal_start_idx = 1;
34-
let ret = null;
62+
if (is_start) {
63+
this.fragmented_nalu = new NALU(payload_type, header.nri, rawData.subarray(nal_start_idx), dts, pts);
64+
} else {
65+
if (this.fragmented_nalu && this.fragmented_nalu.ntype === payload_type) {
66+
this.fragmented_nalu.appendData(rawData.subarray(nal_start_idx));
3567

36-
if ((7 > naltype && 0 < naltype) || (28 > naltype && 8 < naltype)) {
37-
if (this.dts_l != dts) {
38-
this.dts_l = dts;
39-
ret = this.shiftTemp(this.nalu_l);
40-
this.nalu_l = new NALU(naltype, nri, rawData.subarray(nal_start_idx), dts, pts);
41-
} else {
42-
ret = this.shiftTemp(null);
43-
if (this.nalu_l != null) {
44-
this.nalu_l.appendData(new Uint8Array([0, 0, 1]));
45-
this.nalu_l.appendData(rawData.subarray(0));
68+
if (is_end) {
69+
ret = this.fragmented_nalu;
70+
this.fragmented_nalu = null;
71+
return ret;
4672
}
4773
}
48-
return ret;
49-
} else if (naltype == NALU.SPS || naltype == NALU.PPS) {
50-
return [new NALU(naltype, nri, rawData.subarray(nal_start_idx), dts, pts)];
51-
} else if (NALU.FU_A == naltype || NALU.FU_B == naltype) {
52-
let nalfrag = data.getUint8(1);
53-
let nfstart = (nalfrag & 0x80) >>> 7;
54-
let nfend = (nalfrag & 0x40) >>> 6;
55-
let nftype = nalfrag & 0x1F;
74+
}
75+
return null;
76+
}
5677

57-
nal_start_idx++;
58-
let nfdon = 0;
59-
if (NALU.FU_B === naltype) {
60-
nfdon = data.getUint16(2);
61-
nal_start_idx += 2;
62-
}
63-
if (this.dts_l != dts) {
64-
if (nfstart) {
65-
ret = this.shiftTemp(this.nalu_l);
66-
this.nalu_l = new NALU(nftype, nri + nftype, rawData.subarray(nal_start_idx), dts, pts);
67-
this.dts_l = dts;
68-
} else {
69-
ret = this.shiftTemp(null);
70-
console.log("fu packet error");
71-
}
72-
} else {
73-
if (this.nalu_l != null) {
74-
if (this.nalu_l.ntype == nftype) {
75-
ret = this.shiftTemp(null);
76-
if (nfstart) {
77-
this.nalu_l.appendData(new Uint8Array([0, 0, 1, nri + nftype]));
78-
this.nalu_l.appendData(rawData.subarray(nal_start_idx));
79-
} else {
80-
this.nalu_l.appendData(rawData.subarray(nal_start_idx));
81-
}
82-
} else {
83-
if (nfstart) {
84-
ret = this.shiftTemp(this.nalu_l);
85-
this.nalu_l = new NALU(nftype, nri + nftype, rawData.subarray(nal_start_idx), dts, pts);
86-
this.dts_l = dts;
87-
} else {
88-
ret = this.shiftTemp(null);
89-
console.log("fu packet error");
90-
}
91-
}
92-
} else {
93-
ret = this.shiftTemp(null);
94-
console.log("fu packet start without head");
95-
}
96-
}
97-
return ret;
78+
onNALUFragment(rawData, dts, pts) {
79+
80+
let data = new DataView(rawData.buffer, rawData.byteOffset, rawData.byteLength);
81+
82+
let header = NALUAsm.parseNALHeader(data.getUint8(0));
83+
84+
let nal_start_idx = 1;
85+
86+
let unit = null;
87+
if (header.type > 0 && header.type < 24) {
88+
unit = this.parseSingleNALUPacket(rawData.subarray(nal_start_idx), header, dts, pts);
89+
} else if (NALU.FU_A === header.type || NALU.FU_B === header.type) {
90+
unit = this.parseFragmentationUnit(rawData.subarray(nal_start_idx), header, dts, pts);
91+
} else if (NALU.STAP_A === header.type || NALU.STAP_B === header.type) {
92+
return this.parseAggregationPacket(rawData.subarray(nal_start_idx), header, dts, pts);
9893
} else {
9994
/* 30 - 31 is undefined, ignore those (RFC3984). */
100-
Log.log('Undefined NAL unit, type: ' + naltype);
101-
ret = this.shiftTemp(null);
102-
return ret;
95+
Log.log('Undefined NAL unit, type: ' + header.type);
96+
return null;
97+
}
98+
if (unit) {
99+
return [unit];
103100
}
101+
return null;
104102
}
105103
}

src/core/parsers/h264.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ export class H264Parser {
6868
break;
6969
default:
7070
}
71+
if (unit.nri!=0) {
72+
push=true;
73+
}
7174
return push;
7275
}
7376

src/core/parsers/sdp.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export class SDPParser {
118118
}
119119

120120
_parseOrigin(line) {
121-
let matches = line.match(/^o=([^ ]+) ([0-9]+) ([0-9]+) (IN) (IP4|IP6) ([^ ]+)$/);
121+
let matches = line.match(/^o=([^ ]+) (-?[0-9]+) (-?[0-9]+) (IN) (IP4|IP6) ([^ ]+)$/);
122122
if (!matches || !matches.length) {
123123
Log.log('\'o=\' (Origin) formatted incorrectly: ' + line);
124124
return false;

0 commit comments

Comments
 (0)