Skip to content

Commit

Permalink
Merge pull request #507 from shiguredo/feature/mp4-media-stream-aac
Browse files Browse the repository at this point in the history
`Mp4MediaStream` の対応コーデックに AAC を追加する
  • Loading branch information
sile authored Dec 6, 2024
2 parents 36ce969 + 9a9658e commit 812fb5d
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 29 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

## develop

- [ADD] `Mp4MediaStream` の対応コーデックに AAC を追加する
- @sile

### misc

## mp4-media-stream-2024.2.0
Expand Down
38 changes: 19 additions & 19 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion packages/mp4-media-stream/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ video.srcObject = stream
## 未対応機能

以下の機能には現時点では対応していません:
- H.264 / Opus 以外のコーデックを含んだ MP4 の再生
- H.264 / Opus / AAC 以外のコーデックを含んだ MP4 の再生
- 再生開始位置の指定(シーク)
- 再生の一時停止・再開
- 数 GB を超える MP4 ファイルの再生
Expand Down
8 changes: 1 addition & 7 deletions packages/mp4-media-stream/src/mp4_media_stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,8 @@ class Mp4MediaStream {
}

try {
if (data.format !== 'f32') {
// フォーマットは f32 だけが来る想定。
// もし他のフォーマットが来ることがあれば、その都度対応すること。
throw Error(`Unsupported audio data format: ${data.format}"`)
}

const samples = new Float32Array(data.numberOfFrames * data.numberOfChannels)
data.copyTo(samples, { planeIndex: 0 })
data.copyTo(samples, { planeIndex: 0, format: 'f32' })
data.close()

const timestamp = data.timestamp
Expand Down
2 changes: 1 addition & 1 deletion packages/mp4-media-stream/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ futures = "0.3.31"
orfail = { version = "1.1.0", features = ["serde"] }
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
shiguredo_mp4 = "2024.3.0"
shiguredo_mp4 = "2024.4.0"
32 changes: 31 additions & 1 deletion packages/mp4-media-stream/wasm/src/mp4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use serde::Serialize;
use shiguredo_mp4::{
aux::SampleTableAccessor,
boxes::{
Avc1Box, FtypBox, HdlrBox, IgnoredBox, MoovBox, OpusBox, SampleEntry, StblBox, TrakBox,
Avc1Box, FtypBox, HdlrBox, IgnoredBox, MoovBox, Mp4aBox, OpusBox, SampleEntry, StblBox,
TrakBox,
},
BaseBox, Decode, Either, Encode,
};
Expand Down Expand Up @@ -55,6 +56,31 @@ impl AudioDecoderConfig {
number_of_channels: b.audio.channelcount as u8,
}
}

pub fn from_mp4a_box(b: &Mp4aBox) -> Self {
let mut codec = format!(
"mp4a.{:02X}",
b.esds_box.es.dec_config_descr.object_type_indication
);
if b.esds_box.es.dec_config_descr.object_type_indication == 0x40 {
if let Some(b) = b
.esds_box
.es
.dec_config_descr
.dec_specific_info
.payload
.get(0)
{
let audio_object_type = b >> 3;
codec.push_str(&format!(".{audio_object_type}"));
}
};
Self {
codec,
sample_rate: b.audio.samplerate.integer,
number_of_channels: b.audio.channelcount as u8,
}
}
}

#[derive(Debug, Serialize)]
Expand Down Expand Up @@ -86,6 +112,7 @@ impl Track {
match sample_table.stbl_box().stsd_box.entries.first() {
Some(SampleEntry::Avc1(_)) => (),
Some(SampleEntry::Opus(_)) => (),
Some(SampleEntry::Mp4a(_)) => (),
Some(b) => {
return Err(Failure::new(format!(
"Unsupported {kind}codec: {}",
Expand Down Expand Up @@ -177,6 +204,9 @@ impl Mp4 {
SampleEntry::Opus(b) => {
audio_configs.push(AudioDecoderConfig::from_opus_box(b));
}
SampleEntry::Mp4a(b) => {
audio_configs.push(AudioDecoderConfig::from_mp4a_box(b));
}
_ => {
// `Track` 作成時にチェックしているのでここには来ない
unreachable!()
Expand Down
4 changes: 4 additions & 0 deletions packages/mp4-media-stream/wasm/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ impl TrackPlayer {
let config = AudioDecoderConfig::from_opus_box(b);
WasmApi::create_audio_decoder(self.player_id, config).await
}
SampleEntry::Mp4a(b) => {
let config = AudioDecoderConfig::from_mp4a_box(b);
WasmApi::create_audio_decoder(self.player_id, config).await
}
_ => {
// MP4::load() の中で非対応コーデックのチェックは行っているので、ここに来ることはない
unreachable!()
Expand Down

0 comments on commit 812fb5d

Please sign in to comment.