Skip to content

Commit

Permalink
fix: use ISOM tracks instead of SDP as start of movie
Browse files Browse the repository at this point in the history
The start of a new movie is indicated by the tracks
property present on the ISOM box, as the SDP is no
longer transmitted after the MP4 muxer.
  • Loading branch information
steabert committed May 18, 2021
1 parent 24963d5 commit c6809d9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 27 deletions.
21 changes: 13 additions & 8 deletions lib/components/mp4capture/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ const MOCK_BUFFER_SIZE = 10 // Jest has problems with large buffers
const MOCK_MOVIE_DATA = 0xff
const MOCK_MOVIE_ENDING_DATA = 0xfe

// A movie consists of ISOM packets, starting with an SDP packet.
// We want to simulate the beginning and end of a movie, as well
// as non-movie packets.
const MOCK_MOVIE = [MessageType.SDP, MessageType.ISOM, MessageType.ISOM].map(
(type) => {
return { type, data: Buffer.allocUnsafe(1).fill(MOCK_MOVIE_DATA) }
},
)
// A movie consists of ISOM packets, starting with an ISOM message that has a
// tracks property. We want to simulate the beginning and end of a movie, as
// well as non-movie packets.
const MOCK_MOVIE = [MessageType.ISOM, MessageType.ISOM].map((type, idx) => {
if (idx === 0) {
return {
type,
tracks: [],
data: Buffer.allocUnsafe(1).fill(MOCK_MOVIE_DATA),
}
}
return { type, data: Buffer.allocUnsafe(1).fill(MOCK_MOVIE_DATA) }
})
const MOCK_MOVIE_BUFFER = Buffer.alloc(2).fill(MOCK_MOVIE_DATA)

const MOCK_MOVIE_ENDING = [
Expand Down
34 changes: 15 additions & 19 deletions lib/components/mp4capture/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import debug from 'debug'
import { Tube } from '../component'
import { Transform } from 'stream'
import { MessageType } from '../message'
import { Message, MessageType } from '../message'

const MAX_CAPTURE_BYTES = 225000000 // 5 min at a rate of 6 Mbit/s

/**
* Component that records MP4 data.
*
* @extends Component
*/
export class Mp4Capture extends Tube {
private _active: boolean
Expand All @@ -17,21 +15,22 @@ export class Mp4Capture extends Tube {
private _bufferOffset: number
private readonly _bufferSize: number
private _buffer: Buffer
/**
* Create a new mp4muxer component.
* @return {undefined}
*/

constructor(maxSize = MAX_CAPTURE_BYTES) {
const incoming = new Transform({
objectMode: true,
transform: (msg, encoding, callback) => {
if (msg.type === MessageType.SDP) {
// Arrival of SDP indicates new movie, start recording if active.
if (this._active) {
this._capture = true
}
} else if (this._capture && msg.type === MessageType.ISOM) {
// MP4 box has arrived, record if appropriate
transform: (msg: Message, _encoding, callback) => {
// Arrival of ISOM with tracks indicates new movie, start recording if active.
if (
this._active &&
msg.type === MessageType.ISOM &&
msg.tracks !== undefined
) {
this._capture = true
}

// If capture enabled, record all ISOM (MP4) boxes
if (this._capture && msg.type === MessageType.ISOM) {
if (
this._bufferOffset <
this._buffer.byteLength - msg.data.byteLength
Expand Down Expand Up @@ -70,8 +69,7 @@ export class Mp4Capture extends Tube {
* and will terminate when the movie ends or when the buffer is full. On
* termination, the callback you passed will be called with the captured
* data as argument.
* @public
* @param callback Will be called when data is captured.
* @param callback Will be called when data is captured.
*/
start(callback: (buffer: Buffer) => void) {
if (!this._active) {
Expand All @@ -89,8 +87,6 @@ export class Mp4Capture extends Tube {
/**
* Deactivate video capture. This ends an ongoing capture and prevents
* any further capturing.
* @public
* @return {undefined}
*/
stop() {
if (this._active) {
Expand Down

0 comments on commit c6809d9

Please sign in to comment.