Skip to content

Commit

Permalink
feat: Allow generate muxed content with Mp4Generator
Browse files Browse the repository at this point in the history
  • Loading branch information
avelad committed Aug 30, 2023
1 parent eec25b2 commit f6b9563
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 204 deletions.
4 changes: 3 additions & 1 deletion lib/mss/mss_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,8 @@ shaka.mss.MssParser = class {
}
/** @type {shaka.util.Mp4Generator.StreamInfo} */
const streamInfo = {
id: stream.id,
type: stream.type,
encrypted: stream.encrypted,
timescale: stream.mssPrivateData.timescale,
duration: stream.mssPrivateData.duration,
Expand All @@ -642,7 +644,7 @@ shaka.mss.MssParser = class {
data: null, // Data is not necessary for init segement.
stream: stream,
};
const mp4Generator = new shaka.util.Mp4Generator(streamInfo);
const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
initSegmentData = mp4Generator.initSegment();
this.initSegmentDataByStreamId_.set(stream.id, initSegmentData);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/transmuxer/aac_transmuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ shaka.transmuxer.AacTransmuxer = class {
stream.audioSamplingRate = info.sampleRate;
stream.channelsCount = info.channelCount;
stream.codecs = info.codec;
stream.type = 'audio';

/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
const samples = [];
Expand Down Expand Up @@ -188,6 +187,8 @@ shaka.transmuxer.AacTransmuxer = class {

/** @type {shaka.util.Mp4Generator.StreamInfo} */
const streamInfo = {
id: stream.id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -201,7 +202,7 @@ shaka.transmuxer.AacTransmuxer = class {
},
stream: stream,
};
const mp4Generator = new shaka.util.Mp4Generator(streamInfo);
const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
let initSegment;
if (!this.initSegments.has(stream.id)) {
initSegment = mp4Generator.initSegment();
Expand Down
4 changes: 3 additions & 1 deletion lib/transmuxer/ac3_transmuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ shaka.transmuxer.Ac3Transmuxer = class {

/** @type {shaka.util.Mp4Generator.StreamInfo} */
const streamInfo = {
id: stream.id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -188,7 +190,7 @@ shaka.transmuxer.Ac3Transmuxer = class {
},
stream: stream,
};
const mp4Generator = new shaka.util.Mp4Generator(streamInfo);
const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
let initSegment;
if (!this.initSegments.has(stream.id)) {
initSegment = mp4Generator.initSegment();
Expand Down
4 changes: 3 additions & 1 deletion lib/transmuxer/ec3_transmuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ shaka.transmuxer.Ec3Transmuxer = class {

/** @type {shaka.util.Mp4Generator.StreamInfo} */
const streamInfo = {
id: stream.id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -188,7 +190,7 @@ shaka.transmuxer.Ec3Transmuxer = class {
},
stream: stream,
};
const mp4Generator = new shaka.util.Mp4Generator(streamInfo);
const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
let initSegment;
if (!this.initSegments.has(stream.id)) {
initSegment = mp4Generator.initSegment();
Expand Down
4 changes: 3 additions & 1 deletion lib/transmuxer/mp3_transmuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ shaka.transmuxer.Mp3Transmuxer = class {

/** @type {shaka.util.Mp4Generator.StreamInfo} */
const streamInfo = {
id: stream.id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -180,7 +182,7 @@ shaka.transmuxer.Mp3Transmuxer = class {
},
stream: stream,
};
const mp4Generator = new shaka.util.Mp4Generator(streamInfo);
const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
let initSegment;
if (!this.initSegments.has(stream.id)) {
initSegment = mp4Generator.initSegment();
Expand Down
83 changes: 66 additions & 17 deletions lib/transmuxer/ts_transmuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,45 +180,59 @@ shaka.transmuxer.TsTransmuxer = class {
if (startTime.video != null) {
timestamp = startTime.video;
}
let streamInfo;
const streamInfos = [];
const codecs = tsParser.getCodecs();
try {
let streamInfo = null;
switch (codecs.video) {
case 'avc':
streamInfo =
this.getAvcStreamInfo_(tsParser, timestamp, stream, duration);
break;
}
if (streamInfo) {
streamInfos.push(streamInfo);
streamInfo = null;
}
const isMuxed = !!(codecs.video && codecs.audio);
switch (codecs.audio) {
case 'aac':
streamInfo =
this.getAacStreamInfo_(tsParser, timestamp, stream, duration);
this.getAacStreamInfo_(
tsParser, timestamp, stream, duration, isMuxed);
break;
case 'ac3':
streamInfo =
this.getAc3StreamInfo_(tsParser, timestamp, stream, duration);
this.getAc3StreamInfo_(
tsParser, timestamp, stream, duration, isMuxed);
break;
case 'ec3':
streamInfo =
this.getEc3StreamInfo_(tsParser, timestamp, stream, duration);
this.getEc3StreamInfo_(
tsParser, timestamp, stream, duration, isMuxed);
break;
case 'mp3':
streamInfo =
this.getMp3StreamInfo_(tsParser, timestamp, stream, duration);
this.getMp3StreamInfo_(
tsParser, timestamp, stream, duration, isMuxed);
break;
}
switch (codecs.video) {
case 'avc':
streamInfo =
this.getAvcStreamInfo_(tsParser, timestamp, stream, duration);
break;
if (streamInfo) {
streamInfos.push(streamInfo);
streamInfo = null;
}
} catch (e) {
return Promise.reject(e);
}

if (!streamInfo) {
if (!streamInfos.length) {
return Promise.reject(new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MEDIA,
shaka.util.Error.Code.TRANSMUXING_FAILED));
}

const mp4Generator = new shaka.util.Mp4Generator(streamInfo);
const mp4Generator = new shaka.util.Mp4Generator(streamInfos);
let initSegment;
if (!this.initSegments.has(stream.id)) {
initSegment = mp4Generator.initSegment();
Expand All @@ -239,10 +253,11 @@ shaka.transmuxer.TsTransmuxer = class {
* @param {number} timestamp
* @param {shaka.extern.Stream} stream
* @param {number} duration
* @param {boolean} isMuxed
* @return {shaka.util.Mp4Generator.StreamInfo}
* @private
*/
getAacStreamInfo_(tsParser, timestamp, stream, duration) {
getAacStreamInfo_(tsParser, timestamp, stream, duration, isMuxed) {
const ADTS = shaka.transmuxer.ADTS;

/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
Expand All @@ -266,7 +281,6 @@ shaka.transmuxer.TsTransmuxer = class {
stream.audioSamplingRate = info.sampleRate;
stream.channelsCount = info.channelCount;
stream.codecs = info.codec;
stream.type = 'audio';

while (offset < data.length) {
const header = ADTS.parseHeader(data, offset);
Expand Down Expand Up @@ -311,7 +325,13 @@ shaka.transmuxer.TsTransmuxer = class {
/** @type {number} */
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);

let id = stream.id;
if (isMuxed) {
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
}
return {
id: id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -333,10 +353,11 @@ shaka.transmuxer.TsTransmuxer = class {
* @param {number} timestamp
* @param {shaka.extern.Stream} stream
* @param {number} duration
* @param {boolean} isMuxed
* @return {shaka.util.Mp4Generator.StreamInfo}
* @private
*/
getAc3StreamInfo_(tsParser, timestamp, stream, duration) {
getAc3StreamInfo_(tsParser, timestamp, stream, duration, isMuxed) {
const Ac3 = shaka.transmuxer.Ac3;

/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
Expand Down Expand Up @@ -394,7 +415,13 @@ shaka.transmuxer.TsTransmuxer = class {
/** @type {number} */
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);

let id = stream.id;
if (isMuxed) {
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
}
return {
id: id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -416,10 +443,11 @@ shaka.transmuxer.TsTransmuxer = class {
* @param {number} timestamp
* @param {shaka.extern.Stream} stream
* @param {number} duration
* @param {boolean} isMuxed
* @return {shaka.util.Mp4Generator.StreamInfo}
* @private
*/
getEc3StreamInfo_(tsParser, timestamp, stream, duration) {
getEc3StreamInfo_(tsParser, timestamp, stream, duration, isMuxed) {
const Ec3 = shaka.transmuxer.Ec3;

/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
Expand Down Expand Up @@ -477,7 +505,13 @@ shaka.transmuxer.TsTransmuxer = class {
/** @type {number} */
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);

let id = stream.id;
if (isMuxed) {
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
}
return {
id: id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand All @@ -499,10 +533,11 @@ shaka.transmuxer.TsTransmuxer = class {
* @param {number} timestamp
* @param {shaka.extern.Stream} stream
* @param {number} duration
* @param {boolean} isMuxed
* @return {shaka.util.Mp4Generator.StreamInfo}
* @private
*/
getMp3StreamInfo_(tsParser, timestamp, stream, duration) {
getMp3StreamInfo_(tsParser, timestamp, stream, duration, isMuxed) {
const MpegAudio = shaka.transmuxer.MpegAudio;

/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
Expand Down Expand Up @@ -555,7 +590,13 @@ shaka.transmuxer.TsTransmuxer = class {
/** @type {number} */
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);

let id = stream.id;
if (isMuxed) {
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
}
return {
id: id,
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: sampleRate,
duration: duration,
Expand Down Expand Up @@ -643,6 +684,8 @@ shaka.transmuxer.TsTransmuxer = class {
stream.width = info.width;

return {
id: stream.id,
type: shaka.util.ManifestParserUtils.ContentType.VIDEO,
encrypted: stream.encrypted && stream.drmInfos.length > 0,
timescale: timescale,
duration: duration,
Expand Down Expand Up @@ -682,6 +725,12 @@ shaka.transmuxer.TsTransmuxer.SUPPORTED_VIDEO_CODECS_ = [
'avc',
];

/**
* @private
* @const {number}
*/
shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_ = 128;


shaka.transmuxer.TransmuxerEngine.registerTransmuxer(
'video/mp2t',
Expand Down
Loading

0 comments on commit f6b9563

Please sign in to comment.