mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-14 08:26:16 -08:00
优化amf解析
This commit is contained in:
1 parent
3afe2e1640
commit
32b2f4792a
9 files changed
+190
-119
No files matched your search
@@ -36,7 +36,7 @@ export default function fetchStream(flv, url) {
|
||||
read();
|
||||
})
|
||||
.catch(error => {
|
||||
flv.emit('flvFetchError', error);
|
||||
throw error;
|
||||
});
|
||||
})();
|
||||
},
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { getUint8Sum, readUint8, bin2String, bin2Boolean, bin2Float } from '../utils';
|
||||
import { getUint8Sum, readUint8, bin2String, bin2Boolean, bin2Float, errorHandle } from '../utils';
|
||||
|
||||
export default function getMetaData(scripTag) {
|
||||
const readScripTag = readUint8(scripTag.body);
|
||||
const metadata = Object.create(null);
|
||||
const amf1 = Object.create(null);
|
||||
const amf2 = Object.create(null);
|
||||
|
||||
[amf1.type] = readScripTag(1);
|
||||
errorHandle(amf1.type === 2, `AMF: [amf1] type expect 2, but got ${amf1.type}`);
|
||||
amf1.size = getUint8Sum(readScripTag(2));
|
||||
amf1.string = bin2String(readScripTag(amf1.size));
|
||||
|
||||
[amf2.type] = readScripTag(1);
|
||||
errorHandle(amf2.type === 8, `AMF: [amf1] type expect 8, but got ${amf2.type}`);
|
||||
amf2.size = getUint8Sum(readScripTag(4));
|
||||
amf2.metaData = Object.create(null);
|
||||
|
||||
@@ -45,8 +49,8 @@ export default function getMetaData(scripTag) {
|
||||
}
|
||||
case 8: {
|
||||
value = Object.create(null);
|
||||
let endObject = false;
|
||||
while (!endObject && readScripTag.index < scripTag.body.length) {
|
||||
let endArray = false;
|
||||
while (!endArray && readScripTag.index < scripTag.body.length) {
|
||||
const nameLength = getUint8Sum(readScripTag(2));
|
||||
const name = bin2String(readScripTag(nameLength));
|
||||
const type = readScripTag(1)[0];
|
||||
@@ -54,7 +58,7 @@ export default function getMetaData(scripTag) {
|
||||
value[name] = getValue(type);
|
||||
}
|
||||
if (type === 9) {
|
||||
endObject = true;
|
||||
endArray = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -74,7 +78,7 @@ export default function getMetaData(scripTag) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.warn(`AMF: Unknown metaData type: ${type} in ${readScripTag.index - 1}`);
|
||||
errorHandle(false, `AMF: Unknown metaData type: ${type}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -90,6 +94,9 @@ export default function getMetaData(scripTag) {
|
||||
}
|
||||
}
|
||||
|
||||
errorHandle(readScripTag.index === scripTag.body.length, 'AMF: Seems to be incompletely parsed');
|
||||
errorHandle(amf2.size === Object.keys(amf2.metaData).length, 'AMF: [amf2] length does not match');
|
||||
|
||||
metadata.amf1 = amf1;
|
||||
metadata.amf2 = amf2;
|
||||
return metadata;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import fetchStream from './fetchStream';
|
||||
import readFile from './readFile';
|
||||
import getMetaData from './getMetaData';
|
||||
import { mergeTypedArrays, getUint8Sum } from '../utils';
|
||||
import { mergeTypedArrays, getUint8Sum, bin2String } from '../utils';
|
||||
|
||||
export default class FlvParse {
|
||||
constructor(flv) {
|
||||
this.flv = flv;
|
||||
const { url } = flv.options;
|
||||
const { url, debug } = flv.options;
|
||||
this.uint8 = new Uint8Array(0);
|
||||
this.index = 0;
|
||||
this.header = null;
|
||||
@@ -15,15 +15,15 @@ export default class FlvParse {
|
||||
this.done = false;
|
||||
|
||||
flv.on('flvFetchStart', () => {
|
||||
console.log('[flv-fetch-start]');
|
||||
if (debug) {
|
||||
console.log('[flv-fetch-start]', url);
|
||||
}
|
||||
});
|
||||
|
||||
flv.on('flvFetchCancel', () => {
|
||||
console.log('[flv-fetch-cancel]');
|
||||
});
|
||||
|
||||
flv.on('flvFetchError', error => {
|
||||
console.log('[flv-fetch-error]', error);
|
||||
if (debug) {
|
||||
console.log('[flv-fetch-cancel]');
|
||||
}
|
||||
});
|
||||
|
||||
flv.on('flvFetching', uint8 => {
|
||||
@@ -32,7 +32,9 @@ export default class FlvParse {
|
||||
});
|
||||
|
||||
flv.on('flvFetchEnd', uint8 => {
|
||||
console.log('[flv-fetch-end]');
|
||||
if (debug) {
|
||||
console.log('[flv-fetch-end]');
|
||||
}
|
||||
this.done = true;
|
||||
if (uint8) {
|
||||
this.uint8 = uint8;
|
||||
@@ -42,7 +44,10 @@ export default class FlvParse {
|
||||
this.tags = [];
|
||||
this.parse();
|
||||
}
|
||||
flv.emit('parseDone');
|
||||
flv.emit('flvParseDone');
|
||||
if (debug) {
|
||||
console.log('[flv-parse-done]');
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof url === 'string') {
|
||||
@@ -53,41 +58,48 @@ export default class FlvParse {
|
||||
}
|
||||
|
||||
parse() {
|
||||
const { debug } = this.flv.options;
|
||||
if (this.uint8.length >= 13 && !this.header) {
|
||||
const header = Object.create(null);
|
||||
header.signature = this.read(3);
|
||||
header.version = this.read(1);
|
||||
header.flags = this.read(1);
|
||||
header.headersize = this.read(4);
|
||||
header.signature = bin2String(this.read(3));
|
||||
[header.version] = this.read(1);
|
||||
[header.flags] = this.read(1);
|
||||
header.headersize = getUint8Sum(this.read(4));
|
||||
this.header = header;
|
||||
this.read(4);
|
||||
this.flv.emit('parseHeader', this.header);
|
||||
console.log(this.header);
|
||||
this.flv.emit('flvParseHeader', this.header);
|
||||
if (debug) {
|
||||
console.log('[flv-parse-header]', this.header);
|
||||
}
|
||||
}
|
||||
|
||||
while (this.index < this.uint8.length) {
|
||||
const tag = Object.create(null);
|
||||
tag.tagType = this.read(1);
|
||||
tag.dataSize = this.read(3);
|
||||
[tag.tagType] = this.read(1);
|
||||
tag.dataSize = getUint8Sum(this.read(3));
|
||||
tag.timestamp = this.read(4);
|
||||
tag.streamID = this.read(3);
|
||||
tag.body = this.read(getUint8Sum(tag.dataSize));
|
||||
tag.body = this.read(tag.dataSize);
|
||||
this.tags.push(tag);
|
||||
this.read(4);
|
||||
this.flv.emit('parseTag', tag);
|
||||
this.flv.emit('flvParseTag', tag);
|
||||
}
|
||||
|
||||
if (this.tags.length > 1 && this.tags[0].tagType[0] === 18 && !this.metadata) {
|
||||
this.flv.emit('flvParseTags', this.tags);
|
||||
|
||||
if (this.tags.length > 1 && this.tags[0].tagType === 18 && !this.metadata) {
|
||||
this.metadata = getMetaData(this.tags[0]);
|
||||
this.flv.emit('parseMetadata', this.metadata);
|
||||
console.log(this.metadata);
|
||||
if (debug) {
|
||||
console.log('[flv-parse-metadata]', this.metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
read(length) {
|
||||
const tempUint8 = [];
|
||||
const tempUint8 = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
tempUint8.push(this.uint8[this.index]);
|
||||
tempUint8[i] = this.uint8[this.index];
|
||||
this.index += 1;
|
||||
}
|
||||
return tempUint8;
|
||||
|
||||
@@ -26,6 +26,7 @@ class Flv extends Emitter {
|
||||
return {
|
||||
mediaElement: '',
|
||||
url: '',
|
||||
debug: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -53,15 +53,19 @@ export function bin2Boolean(bin) {
|
||||
return bin === 1;
|
||||
}
|
||||
|
||||
export function log(name, msg = '') {
|
||||
console.log(`[${name}] ${msg}`);
|
||||
}
|
||||
|
||||
export function readUint8(uint8) {
|
||||
let index = 0;
|
||||
return function read(length) {
|
||||
const result = [];
|
||||
const tempUint8 = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
result.push(uint8[index]);
|
||||
tempUint8[i] = uint8[index];
|
||||
index += 1;
|
||||
}
|
||||
read.index = index;
|
||||
return result;
|
||||
return tempUint8;
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user