Skip to content

Commit

Permalink
nal u
Browse files Browse the repository at this point in the history
  • Loading branch information
yqjiang committed Sep 20, 2019
1 parent 92be35a commit 8bcc316
Show file tree
Hide file tree
Showing 2 changed files with 251 additions and 0 deletions.
97 changes: 97 additions & 0 deletions packages/xgplayer-hls-live/src/playlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
class Playlist {
constructor (configs) {
this._baseURL = '';
this._list = {};
this._ts = {};
this.version = 0;
this.sequence = -1;
this.targetduration = 0;
this.duration = 0;
this._lastget = undefined;
this._audoclear = configs.autoclear || false;
}

get list () {
return this._list;
}

set baseURL (baseURL) {
if (this.baseURL !== baseURL) {
this.clear();
this._baseURL = baseURL;
}
}

get baseURL () {
return this._baseURL;
}

push (ts, duration) {
this._ts[ts] = {duration: duration, downloaded: false, start: this.duration};
this._list[this.duration] = ts;
this.duration += duration;
}

pushM3U8 (data) {
// 常规信息替换
this.version = data.version;
this.targetduration = data.targetduration;

// 新分片信息
if (data.sequence > this.sequence) {
this.sequence = data.sequence;
for (let i = 0; i < data.frags.length; i++) {
let frag = data.frags[i];
if (!this._ts[frag.url]) {
this.push(frag.url, frag.duration);
}
}
}
}

getTs (time) {
let timelist = Object.keys(this._list);
let ts;

if (time === undefined) {
if (this._lastget) {
time = this._lastget.time + this._lastget.duration;
} else {
time = 0;
}
}

if (timelist.length < 1 || time >= this.duration) {
return undefined;
}

for (let i = 0; i < timelist.length; i++) {
if (time >= timelist[i]) {
let url = this._list[timelist[i]];
let downloaded = this._ts[url].downloaded;
ts = {url, downloaded, time: parseInt(timelist[i]), duration: parseInt(this._ts[url].duration)};
if (this.autoclear) {
delete this._ts[this._lastget.url];
delete this._list[this._lastget.time];
}
this._lastget = ts;
} else {
break;
}
}

return ts;
}

clear () {
this._baseURL = '';
this._list = {};
this._ts = {};
this.version = 0;
this.sequence = -1;
this.targetduration = 0;
this.duration = 0;
}
}

export default Playlist;
154 changes: 154 additions & 0 deletions packages/xgplayer-utils/src/h264/nalunit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import SpsParser from './spsParser';
class Nalunit {
static getNalunits (buffer) {
if (buffer.length - buffer.position < 4) {
return [];
}

let buf = buffer.dataview;
let position = buffer.position;
if (buf.getInt32(position) === 1 ||
(buf.getInt16(position) === 0 && buf.getInt8(position + 2) === 1)) {
return Nalunit.getAnnexbNals(buffer);
} else {
return Nalunit.getAvccNals(buffer);
}
}

static getAnnexbNals (buffer) {
let nals = [];
let position = Nalunit.getHeaderPositionAnnexB(buffer);
let start = position.pos;
let end = start;
while (start < buffer.length - 4) {
let header = buffer.buffer.slice(start, start + position.headerLength);
if (position.pos === buffer.position) {
buffer.skip(position.headerLength);
}
position = Nalunit.getHeaderPositionAnnexB(buffer);
end = position.pos;
let body = new Uint8Array(buffer.buffer.slice(start + header.byteLength, end));
let unit = {header, body};
Nalunit.analyseNal(unit);
nals.push(unit);
buffer.skip(end - buffer.position);
start = end;
}
return nals;
}

static getAvccNals (buffer) {
let nals = [];
while (buffer.position < buffer.length - 4) {
let length = buffer.dataview.getInt32();
if (buffer.length - buffer.position >= length) {
let header = buffer.buffer.slice(buffer.position, buffer.position + 4);
buffer.skip(4)
let body = buffer.buffer.slice(buffer.position, buffer.position + length);
buffer.skip(length);
let unit = {header, body};
Nalunit.analyseNal(unit);
nals.push(unit);
} else {
break;
}
}
return nals;
}

static analyseNal (unit) {
let type = unit.body[0] & 0x1f;
switch (type) {
case 1:
// NDR
unit.ndr = true;
break;
case 5:
// IDR
unit.idr = true;
break;
case 6:
// SEI
break;
case 7:
// SPS
unit.sps = SpsParser.parseSPS(unit.body);
console.log(unit);
break;
case 8:
// PPS
unit.pps = true;
break;
case 9:
// AUD
break;
default:
break;
}
}

static getHeaderPositionAnnexB (buffer) {
// seperate
let pos = buffer.position;
let headerLength = 0;
while (headerLength !== 3 && headerLength !== 4 && pos < buffer.length - 4) {
if (buffer.dataview.getInt16(pos) === 0) {
if (buffer.dataview.getInt16(pos + 2) === 1) {
// 0x000001
headerLength = 4;
} else if (buffer.dataview.getInt8(pos + 2) === 1) {
headerLength = 3;
} else {
pos++;
}
} else {
pos++;
}
}

if (pos === buffer.length - 4) {
if (buffer.dataview.getInt16(pos) === 0) {
if (buffer.dataview.getInt16(pos + 2) === 1) {
// 0x000001
headerLength = 4;
}
} else {
pos++;
if (buffer.dataview.getInt16(pos) === 0 && buffer.dataview.getInt8(pos) === 1) {
// 0x0000001
headerLength = 3;
} else {
pos = buffer.length;
}
}
}
return {pos, headerLength};
}

static getAvcc (sps, pps) {
let ret = new Uint8Array(sps.byteLength + pps.byteLength + 11);
ret[0] = 0x01;
ret[1] = sps[3];
ret[2] = sps[4];
ret[3] = sps[5];
ret[4] = 255;
ret[5] = 225;

let offset = 6;

ret.set(new Uint8Array([(sps.byteLength >>> 8) & 0xff, sps.byteLength & 0xff]), offset);
offset += 2;
ret.set(sps, offset);
offset += sps.byteLength;

ret[offset] = 1;
offset++;

ret.set(new Uint8Array([(pps.byteLength >>> 8) & 0xff, pps.byteLength & 0xff]), offset);
offset += 2;
ret.set(pps, offset);
return ret;
}
}

export default Nalunit;

0 comments on commit 8bcc316

Please sign in to comment.