Skip to content

Commit

Permalink
修复无法找到mdat的bug。
Browse files Browse the repository at this point in the history
  • Loading branch information
kekeqy committed Apr 22, 2019
1 parent 23b9d7e commit 99aaf99
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 11 deletions.
1 change: 1 addition & 0 deletions dist/Channel.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export declare class Channel {
constructor(config: ChannelConfig);
/** 开始封装码流 */
startStreamWrap(): void;
private i;
private broadcast;
/** 结束封装码流 */
stopStreamWrap(): void;
Expand Down
4 changes: 3 additions & 1 deletion dist/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var Channel = /** @class */ (function () {
this.clients = [];
/** 是否正在封装码流 */
this.isStreamWrap = false;
this.i = 0;
this.config = config;
}
/** 开始封装码流 */
Expand All @@ -24,10 +25,11 @@ var Channel = /** @class */ (function () {
return;
this.isStreamWrap = true;
this._mp4Frag = new Mp4Fragment_1.Mp4Fragment(undefined, function (data) { return _this.broadcast(data); });
this._ffmpeg = child_process_1.spawn('ffmpeg', ['-loglevel', 'quiet', '-probesize', '64', '-analyzeduration', '100000', '-reorder_queue_size', '5', '-rtsp_transport', 'tcp', '-i', this.config.url, '-an', '-c:v', 'copy', '-f', 'mp4', '-movflags', '+frag_keyframe+empty_moov+default_base_moof', '-metadata', "title=\"" + this.config.channelname + "\"", '-reset_timestamps', '1', 'pipe:1']);
this._ffmpeg = child_process_1.spawn('ffmpeg', ['-loglevel', 'quiet', '-i', this.config.url, '-an', '-c:v', 'copy', '-f', 'mp4', '-movflags', '+frag_keyframe+empty_moov+default_base_moof', 'pipe:1']);
this._ffmpeg.stdio[1].pipe(this._mp4Frag);
};
Channel.prototype.broadcast = function (data) {
console.log(++this.i);
for (var _i = 0, _a = this.clients; _i < _a.length; _i++) {
var client = _a[_i];
if (client.initSegment)
Expand Down
44 changes: 41 additions & 3 deletions dist/Mp4Fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ var __extends = (this && this.__extends) || (function () {
})();
Object.defineProperty(exports, "__esModule", { value: true });
var stream_1 = require("stream");
var _FTYP = Buffer.from([0x66, 0x74, 0x79, 0x70]); // ftyp
var _MOOV = Buffer.from([0x6D, 0x6F, 0x6F, 0x76]); // moov
var _MOOF = Buffer.from([0x6D, 0x6F, 0x6F, 0x66]); // moof
var _MFRA = Buffer.from([0x6d, 0x66, 0x72, 0x61]); // mfra
var _MDAT = Buffer.from([0x6D, 0x64, 0x61, 0x74]); // mdat
var _MP4A = Buffer.from([0x6d, 0x70, 0x34, 0x61]); // mp4a
var _AVCC = Buffer.from([0x61, 0x76, 0x63, 0x43]); // avcC
/** MP4片段 */
var Mp4Fragment = /** @class */ (function (_super) {
__extends(Mp4Fragment, _super);
Expand Down Expand Up @@ -205,18 +212,49 @@ var Mp4Fragment = /** @class */ (function (_super) {
else {
//mdat第一遍
//第一遍为了确保mdat的启动和获得其大小,很可能块不会包含整个mdat
if (chunk[4] !== 0x6D || chunk[5] !== 0x64 || chunk[6] !== 0x61 || chunk[7] !== 0x74) {
if (chunk.length < 8 || chunk.indexOf(_MDAT) !== 4) {
console.log('无法找到mdat!');
}
var chunkLength = chunk.length;
this._mdatLength = chunk.readUIntBE(0, 4);
this._mdatLength = chunk.readUInt32BE(0, true);
if (this._mdatLength > chunkLength) {
//几乎100%保证超过单个块的大小
this._mdatBuffer = [chunk];
this._mdatBufferSize = chunkLength;
}
else if (this._mdatLength === chunkLength) {
var data = Buffer.concat([this._moof, chunk], (this._moofLength + chunkLength));
delete this._moof;
delete this._moofLength;
delete this._mdatLength;
if (this._readableState.pipesCount > 0) {
this.push(data);
}
if (this._callback) {
this._callback(data);
}
if (this.listenerCount('segment') > 0) {
this.emit('segment', data);
}
this._parseChunk = this._findMoof;
}
else {
console.log('mdat的长度不大于块的长度!');
var data = Buffer.concat([this._moof, chunk], (this._moofLength + this._mdatLength));
var sliceIndex = this._mdatLength;
delete this._moof;
delete this._moofLength;
delete this._mdatLength;
if (this._readableState.pipesCount > 0) {
this.push(data);
}
if (this._callback) {
this._callback(data);
}
if (this.listenerCount('segment') > 0) {
this.emit('segment', data);
}
this._parseChunk = this._findMoof;
this._parseChunk(chunk.slice(sliceIndex));
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sample/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<body>

<video id="mse" muted width="640" height="360"></video>
<video id="mse" muted width="1080" height="720"></video>

<script>
var mime = 'video/mp4; codecs="avc1.64001E"';
Expand Down
4 changes: 3 additions & 1 deletion src/Channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ export class Channel {
if (this.isStreamWrap) return;
this.isStreamWrap = true;
this._mp4Frag = new Mp4Fragment(undefined, data => this.broadcast(data));
this._ffmpeg = spawn('ffmpeg', ['-loglevel', 'quiet', '-probesize', '64', '-analyzeduration', '100000', '-reorder_queue_size', '5', '-rtsp_transport', 'tcp', '-i', this.config.url, '-an', '-c:v', 'copy', '-f', 'mp4', '-movflags', '+frag_keyframe+empty_moov+default_base_moof', '-metadata', `title="${this.config.channelname}"`, '-reset_timestamps', '1', 'pipe:1']);
this._ffmpeg = spawn('ffmpeg', ['-loglevel', 'quiet', '-i', this.config.url, '-an', '-c:v', 'copy', '-f', 'mp4', '-movflags', '+frag_keyframe+empty_moov+default_base_moof', 'pipe:1']);
this._ffmpeg.stdio[1].pipe(this._mp4Frag);
}
private i: number = 0;
private broadcast(data: any): void {
console.log(++this.i);
for (let client of this.clients) {
if ((client as any).initSegment) client.emit('segment', data);
}
Expand Down
46 changes: 42 additions & 4 deletions src/Mp4Fragment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Transform, TransformOptions, TransformCallback } from 'stream';

const _FTYP = Buffer.from([0x66, 0x74, 0x79, 0x70]);// ftyp
const _MOOV = Buffer.from([0x6D, 0x6F, 0x6F, 0x76]);// moov
const _MOOF = Buffer.from([0x6D, 0x6F, 0x6F, 0x66]);// moof
const _MFRA = Buffer.from([0x6d, 0x66, 0x72, 0x61]);// mfra
const _MDAT = Buffer.from([0x6D, 0x64, 0x61, 0x74]);// mdat
const _MP4A = Buffer.from([0x6d, 0x70, 0x34, 0x61]);// mp4a
const _AVCC = Buffer.from([0x61, 0x76, 0x63, 0x43]);// avcC

/** MP4片段 */
export class Mp4Fragment extends Transform {
private _callback: (data: any) => void;
Expand Down Expand Up @@ -197,18 +205,48 @@ export class Mp4Fragment extends Transform {
else {
//mdat第一遍
//第一遍为了确保mdat的启动和获得其大小,很可能块不会包含整个mdat
if (chunk[4] !== 0x6D || chunk[5] !== 0x64 || chunk[6] !== 0x61 || chunk[7] !== 0x74) {
if (chunk.length < 8 || chunk.indexOf(_MDAT) !== 4) {
console.log('无法找到mdat!');
}
const chunkLength = chunk.length;
this._mdatLength = chunk.readUIntBE(0, 4);
this._mdatLength = chunk.readUInt32BE(0, true);
if (this._mdatLength > chunkLength) {
//几乎100%保证超过单个块的大小
this._mdatBuffer = [chunk];
this._mdatBufferSize = chunkLength;
}
else {
console.log('mdat的长度不大于块的长度!');
else if (this._mdatLength === chunkLength) {
const data = Buffer.concat([this._moof, chunk], (this._moofLength + chunkLength));
delete this._moof;
delete this._moofLength;
delete this._mdatLength;
if (this._readableState.pipesCount > 0) {
this.push(data);
}
if (this._callback) {
this._callback(data);
}
if (this.listenerCount('segment') > 0) {
this.emit('segment', data);
}
this._parseChunk = this._findMoof;
} else {
const data = Buffer.concat([this._moof, chunk], (this._moofLength + this._mdatLength));
const sliceIndex = this._mdatLength;
delete this._moof;
delete this._moofLength;
delete this._mdatLength;
if (this._readableState.pipesCount > 0) {
this.push(data);
}
if (this._callback) {
this._callback(data);
}
if (this.listenerCount('segment') > 0) {
this.emit('segment', data);
}
this._parseChunk = this._findMoof;
this._parseChunk(chunk.slice(sliceIndex));
}
}
}
Expand Down

0 comments on commit 99aaf99

Please sign in to comment.