add support for m4a/alac files
This commit is contained in:
parent
462b989f6e
commit
88275bd35f
|
@ -51,6 +51,7 @@ impl TagLibFile {
|
||||||
| TagLibFileType::OggOpus
|
| TagLibFileType::OggOpus
|
||||||
| TagLibFileType::OggSpeex
|
| TagLibFileType::OggSpeex
|
||||||
| TagLibFileType::OggVorbis => true,
|
| TagLibFileType::OggVorbis => true,
|
||||||
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !supported {
|
if !supported {
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub enum TagLibFileType {
|
||||||
OggOpus = 2,
|
OggOpus = 2,
|
||||||
OggSpeex = 3,
|
OggSpeex = 3,
|
||||||
OggVorbis = 4,
|
OggVorbis = 4,
|
||||||
|
MP4 = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use impls::file::*;
|
pub use impls::file::*;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <taglib/vorbisfile.h>
|
#include <taglib/vorbisfile.h>
|
||||||
#include <taglib/oggflacfile.h>
|
#include <taglib/oggflacfile.h>
|
||||||
#include <taglib/opusfile.h>
|
#include <taglib/opusfile.h>
|
||||||
|
#include <taglib/mp4file.h>
|
||||||
#include <taglib/speexfile.h>
|
#include <taglib/speexfile.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -39,6 +40,9 @@ TagLib_File *wrap_taglib_file_new_with_type(const char *filename, short taglib_t
|
||||||
if (taglib_type == 4) {
|
if (taglib_type == 4) {
|
||||||
return reinterpret_cast<TagLib_File *>(new TagLib::Ogg::Vorbis::File(filename));
|
return reinterpret_cast<TagLib_File *>(new TagLib::Ogg::Vorbis::File(filename));
|
||||||
}
|
}
|
||||||
|
if (taglib_type == 5) {
|
||||||
|
return reinterpret_cast<TagLib_File *>(new TagLib::MP4::File(filename));
|
||||||
|
}
|
||||||
return reinterpret_cast<TagLib_File *>(TagLib::FileRef::create(filename));
|
return reinterpret_cast<TagLib_File *>(TagLib::FileRef::create(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ fn transcode_files(
|
||||||
)
|
)
|
||||||
.expect("transcode config error");
|
.expect("transcode config error");
|
||||||
|
|
||||||
let threads = copy_args.threads.unwrap_or(1);
|
let threads = copy_args.threads.unwrap_or(2);
|
||||||
|
|
||||||
if threads > 1 {
|
if threads > 1 {
|
||||||
let files_copy = files.to_vec();
|
let files_copy = files.to_vec();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
pub mod copy;
|
pub mod copy;
|
||||||
#[cfg(feature = "command_genhtml")]
|
#[cfg(feature = "command_genhtml")]
|
||||||
pub mod genhtml;
|
pub mod genhtml;
|
||||||
|
pub mod presets;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
pub mod tags;
|
pub mod tags;
|
||||||
pub mod transcode;
|
pub mod transcode;
|
||||||
pub mod presets;
|
|
||||||
|
|
|
@ -42,9 +42,9 @@ pub fn presets_command(
|
||||||
let preset = match crate::utils::transcoder::presets::get_preset(x.preset) {
|
let preset = match crate::utils::transcoder::presets::get_preset(x.preset) {
|
||||||
Some(preset) => preset,
|
Some(preset) => preset,
|
||||||
None => {
|
None => {
|
||||||
println!("invalid preset specified");
|
println!("invalid preset specified");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match x.format {
|
match x.format {
|
||||||
|
|
|
@ -215,7 +215,7 @@ pub fn process_command(
|
||||||
for file in files.iter_mut() {
|
for file in files.iter_mut() {
|
||||||
rename_file(process_args, file);
|
rename_file(process_args, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "replaygain")]
|
#[cfg(feature = "replaygain")]
|
||||||
if !process_args.skip_replaygain && !process_args.dry_run {
|
if !process_args.skip_replaygain && !process_args.dry_run {
|
||||||
println!("Adding ReplayGain Tags to Files");
|
println!("Adding ReplayGain Tags to Files");
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub enum FileFormat {
|
||||||
AIFF,
|
AIFF,
|
||||||
Wav,
|
Wav,
|
||||||
WavPack,
|
WavPack,
|
||||||
|
M4A,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for FileFormat {
|
impl ToString for FileFormat {
|
||||||
|
@ -37,6 +38,7 @@ impl ToString for FileFormat {
|
||||||
FileFormat::AIFF => "AIFF".to_string(),
|
FileFormat::AIFF => "AIFF".to_string(),
|
||||||
FileFormat::Wav => "Wav".to_string(),
|
FileFormat::Wav => "Wav".to_string(),
|
||||||
FileFormat::WavPack => "WavPack".to_string(),
|
FileFormat::WavPack => "WavPack".to_string(),
|
||||||
|
FileFormat::M4A => "M4A (Unknown)".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +106,9 @@ pub fn detect_format(path: &Path) -> Result<FileFormat, FormatDetectionError> {
|
||||||
"audio/mpeg" => {
|
"audio/mpeg" => {
|
||||||
return Ok(FileFormat::MP3);
|
return Ok(FileFormat::MP3);
|
||||||
}
|
}
|
||||||
|
"audio/m4a" => {
|
||||||
|
return Ok(FileFormat::M4A);
|
||||||
|
}
|
||||||
"audio/x-wav" => {
|
"audio/x-wav" => {
|
||||||
return Ok(FileFormat::Wav);
|
return Ok(FileFormat::Wav);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,8 @@ lazy_static! {
|
||||||
"wav".to_string(),
|
"wav".to_string(),
|
||||||
"wv".to_string(),
|
"wv".to_string(),
|
||||||
"aiff".to_string(),
|
"aiff".to_string(),
|
||||||
|
"m4a".to_string(),
|
||||||
|
"alac".to_string(),
|
||||||
],
|
],
|
||||||
supported_formats: vec![
|
supported_formats: vec![
|
||||||
FileFormat::MP3,
|
FileFormat::MP3,
|
||||||
|
@ -104,6 +106,7 @@ lazy_static! {
|
||||||
FileFormat::Wav,
|
FileFormat::Wav,
|
||||||
FileFormat::WavPack,
|
FileFormat::WavPack,
|
||||||
FileFormat::AIFF,
|
FileFormat::AIFF,
|
||||||
|
FileFormat::M4A,
|
||||||
],
|
],
|
||||||
new: |path, file_format| -> NewHandlerFuncReturn {
|
new: |path, file_format| -> NewHandlerFuncReturn {
|
||||||
let handler = taglib::new_handler(path, file_format)?;
|
let handler = taglib::new_handler(path, file_format)?;
|
||||||
|
@ -122,6 +125,8 @@ lazy_static! {
|
||||||
"wav".to_string(),
|
"wav".to_string(),
|
||||||
"wv".to_string(),
|
"wv".to_string(),
|
||||||
"aiff".to_string(),
|
"aiff".to_string(),
|
||||||
|
"m4a".to_string(),
|
||||||
|
"alac".to_string(),
|
||||||
],
|
],
|
||||||
supported_formats: vec![
|
supported_formats: vec![
|
||||||
FileFormat::MP3,
|
FileFormat::MP3,
|
||||||
|
@ -134,6 +139,7 @@ lazy_static! {
|
||||||
FileFormat::Wav,
|
FileFormat::Wav,
|
||||||
FileFormat::WavPack,
|
FileFormat::WavPack,
|
||||||
FileFormat::AIFF,
|
FileFormat::AIFF,
|
||||||
|
FileFormat::M4A,
|
||||||
],
|
],
|
||||||
new: |path, file_format| -> NewHandlerFuncReturn {
|
new: |path, file_format| -> NewHandlerFuncReturn {
|
||||||
let handler = ffprobe::new_handler(path, file_format)?;
|
let handler = ffprobe::new_handler(path, file_format)?;
|
||||||
|
|
|
@ -74,10 +74,11 @@ impl FormatHandler for TaglibAudioFormat {
|
||||||
FileFormat::OggVorbis
|
FileFormat::OggVorbis
|
||||||
| FileFormat::OggOpus
|
| FileFormat::OggOpus
|
||||||
| FileFormat::OggFLAC
|
| FileFormat::OggFLAC
|
||||||
| FileFormat::OggSpeex // Both "support" ReplayGain but not implemented yet
|
| FileFormat::OggSpeex
|
||||||
// FileFormat::Wav |
|
|
||||||
// FileFormat::WavPack
|
|
||||||
);
|
);
|
||||||
|
// Both "support" ReplayGain but not implemented yet
|
||||||
|
// FileFormat::Wav |
|
||||||
|
// FileFormat::WavPack
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
|
@ -99,20 +100,27 @@ impl FormatHandler for TaglibAudioFormat {
|
||||||
|
|
||||||
fn set_replaygain_data(&mut self, data: ReplayGainRawData) -> Result<(), BoxedError> {
|
fn set_replaygain_data(&mut self, data: ReplayGainRawData) -> Result<(), BoxedError> {
|
||||||
if let Some(format) = self.file_format {
|
if let Some(format) = self.file_format {
|
||||||
let oggtag = self.file.oggtag().expect("oggtag not available?");
|
match format {
|
||||||
|
FileFormat::OggOpus
|
||||||
|
| FileFormat::OggVorbis
|
||||||
|
| FileFormat::OggFLAC
|
||||||
|
| FileFormat::OggSpeex => {
|
||||||
|
let oggtag = self.file.oggtag().expect("oggtag not available?");
|
||||||
|
|
||||||
if format == FileFormat::OggOpus {
|
if format == FileFormat::OggOpus {
|
||||||
let data = data.to_normal(true);
|
let data = data.to_normal(true);
|
||||||
|
|
||||||
oggtag.add_field("R128_TRACK_GAIN".to_string(), data.track_gain);
|
oggtag.add_field("R128_TRACK_GAIN".to_string(), data.track_gain);
|
||||||
} else if matches!(
|
} else {
|
||||||
format,
|
let data = data.to_normal(false);
|
||||||
FileFormat::OggVorbis | FileFormat::OggFLAC | FileFormat::OggSpeex
|
|
||||||
) {
|
|
||||||
let data = data.to_normal(false);
|
|
||||||
|
|
||||||
oggtag.add_field("REPLAYGAIN_TRACK_GAIN".to_string(), data.track_gain);
|
oggtag.add_field("REPLAYGAIN_TRACK_GAIN".to_string(), data.track_gain);
|
||||||
oggtag.add_field("REPLAYGAIN_TRACK_PEAK".to_string(), data.track_peak);
|
oggtag.add_field("REPLAYGAIN_TRACK_PEAK".to_string(), data.track_peak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("setting replaygain not supported on this format");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +160,7 @@ pub fn new_handler(
|
||||||
FileFormat::OggOpus => Some(TagLibFileType::OggOpus),
|
FileFormat::OggOpus => Some(TagLibFileType::OggOpus),
|
||||||
FileFormat::OggFLAC => Some(TagLibFileType::OggFLAC),
|
FileFormat::OggFLAC => Some(TagLibFileType::OggFLAC),
|
||||||
FileFormat::OggSpeex => Some(TagLibFileType::OggSpeex),
|
FileFormat::OggSpeex => Some(TagLibFileType::OggSpeex),
|
||||||
|
FileFormat::M4A => Some(TagLibFileType::MP4),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,4 @@ pub fn add_preset(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
},
|
},
|
||||||
}]),
|
}]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,4 @@ pub fn add_presets(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
name: "g726".to_string(),
|
name: "g726".to_string(),
|
||||||
presets,
|
presets,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ use string_error::into_err;
|
||||||
use crate::utils::transcoder::types::PresetCategory;
|
use crate::utils::transcoder::types::PresetCategory;
|
||||||
use crate::utils::transcoder::types::TranscodeConfig;
|
use crate::utils::transcoder::types::TranscodeConfig;
|
||||||
|
|
||||||
|
mod flac;
|
||||||
|
mod g726;
|
||||||
mod mp3;
|
mod mp3;
|
||||||
mod opus;
|
mod opus;
|
||||||
mod vorbis;
|
|
||||||
mod g726;
|
|
||||||
mod speex;
|
mod speex;
|
||||||
mod flac;
|
mod vorbis;
|
||||||
mod wav;
|
mod wav;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
|
|
@ -36,4 +36,4 @@ pub fn add_presets(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
name: "mp3".to_string(),
|
name: "mp3".to_string(),
|
||||||
presets,
|
presets,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,4 +21,4 @@ pub fn add_presets(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
name: "opus".to_string(),
|
name: "opus".to_string(),
|
||||||
presets,
|
presets,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,4 +21,4 @@ pub fn add_presets(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
name: "vorbis".to_string(),
|
name: "vorbis".to_string(),
|
||||||
presets,
|
presets,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ use crate::utils::transcoder::types::Preset;
|
||||||
use crate::utils::transcoder::types::PresetCategory;
|
use crate::utils::transcoder::types::PresetCategory;
|
||||||
use crate::utils::transcoder::types::TranscodeConfig;
|
use crate::utils::transcoder::types::TranscodeConfig;
|
||||||
|
|
||||||
|
|
||||||
pub fn add_preset(preset_categories: &mut Vec<PresetCategory>) {
|
pub fn add_preset(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
preset_categories.push(PresetCategory {
|
preset_categories.push(PresetCategory {
|
||||||
name: "wav".to_string(),
|
name: "wav".to_string(),
|
||||||
|
@ -15,4 +14,4 @@ pub fn add_preset(preset_categories: &mut Vec<PresetCategory>) {
|
||||||
},
|
},
|
||||||
}]),
|
}]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,11 @@ pub fn transcode(
|
||||||
width = -1;
|
width = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
command_args.extend(vec!["-vf".to_string(), format!("scale={}:{}", width, height)]);
|
command_args.extend(vec![
|
||||||
|
"-vf".to_string(),
|
||||||
|
format!("scale={}:{}", width, height),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
command_args.push(dest);
|
command_args.push(dest);
|
||||||
|
|
Loading…
Reference in a new issue