write concrete MediaFileType

This commit is contained in:
Brandon Thomas committed 2026-07-08 20:53:36 -04:00
1 parent 77643a470e
commit 943fcb44cf
30 files changed
+242 -130

No files matched your search

@@ -26,7 +26,7 @@ pub async fn seed_test_videos(mysql_pool: &Pool<MySql>, user_token: UserToken) -
let media1 = InsertArgs {
pool: &mysql_pool,
maybe_use_apriori_media_token: Some(&model_weight_token1),
media_file_type: MediaFileType::Video,
media_file_type: MediaFileType::Mp4,
maybe_mime_type: Some(&*metadata1.mimetype),
file_size_bytes: metadata1.file_size_bytes,
sha256_checksum: &metadata1.sha256_checksum,
@@ -29,16 +29,16 @@ pub async fn seed_media_files(mysql_pool: &Pool<MySql>, maybe_bucket_clients: Op
// Delete the records if you want to re-seed.
let media_files = [
// Audio
(HANASHI_USER_TOKEN, "m_21jxt406aattq2cna1xtgf5m4mjyyr", MediaFileType::Audio, "media/audio/voice-samples/biden.wav"),
(HANASHI_USER_TOKEN, "m_cxzabpxf88h10rshqraksxbqmhs41h", MediaFileType::Audio, "media/audio/voice-samples/brandon1.wav"),
(HANASHI_USER_TOKEN, "m_sq2vhrrmmbr079afk21543aa2jg53g", MediaFileType::Audio, "media/audio/voice-samples/brandon2.wav"),
(HANASHI_USER_TOKEN, "m_s61a8g3jnddr3xdg3gctsjxxk9jwja", MediaFileType::Audio, "media/audio/voice-samples/elon.wav"),
(HANASHI_USER_TOKEN, "m_e59fh75g76pvebx4qe4r4aymd93q30", MediaFileType::Audio, "media/audio/voice-samples/goku.wav"),
(HANASHI_USER_TOKEN, "m_ttq0ym8ht4v0z87zqz27fhadp0743c", MediaFileType::Audio, "media/audio/voice-samples/hillary.wav"),
(HANASHI_USER_TOKEN, "m_300bv6f141hv553fjf287p5gb76k37", MediaFileType::Audio, "media/audio/voice-samples/mario_impersonator.wav"),
(HANASHI_USER_TOKEN, "m_rd1ey2jem8a37r3vna2h9mht6zevs5", MediaFileType::Audio, "media/audio/voice-samples/rick.wav"),
(HANASHI_USER_TOKEN, "m_8n5epqfvs2vh60khap0s3ezem4epkc", MediaFileType::Audio, "media/audio/voice-samples/trump.wav"),
(HANASHI_USER_TOKEN, "m_g6dpwcpq51e6kvmpbbkdvgxfan9k1k", MediaFileType::Audio, "media/audio/voice-samples/trump_tts.wav"),
(HANASHI_USER_TOKEN, "m_21jxt406aattq2cna1xtgf5m4mjyyr", MediaFileType::Wav, "media/audio/voice-samples/biden.wav"),
(HANASHI_USER_TOKEN, "m_cxzabpxf88h10rshqraksxbqmhs41h", MediaFileType::Wav, "media/audio/voice-samples/brandon1.wav"),
(HANASHI_USER_TOKEN, "m_sq2vhrrmmbr079afk21543aa2jg53g", MediaFileType::Wav, "media/audio/voice-samples/brandon2.wav"),
(HANASHI_USER_TOKEN, "m_s61a8g3jnddr3xdg3gctsjxxk9jwja", MediaFileType::Wav, "media/audio/voice-samples/elon.wav"),
(HANASHI_USER_TOKEN, "m_e59fh75g76pvebx4qe4r4aymd93q30", MediaFileType::Wav, "media/audio/voice-samples/goku.wav"),
(HANASHI_USER_TOKEN, "m_ttq0ym8ht4v0z87zqz27fhadp0743c", MediaFileType::Wav, "media/audio/voice-samples/hillary.wav"),
(HANASHI_USER_TOKEN, "m_300bv6f141hv553fjf287p5gb76k37", MediaFileType::Wav, "media/audio/voice-samples/mario_impersonator.wav"),
(HANASHI_USER_TOKEN, "m_rd1ey2jem8a37r3vna2h9mht6zevs5", MediaFileType::Wav, "media/audio/voice-samples/rick.wav"),
(HANASHI_USER_TOKEN, "m_8n5epqfvs2vh60khap0s3ezem4epkc", MediaFileType::Wav, "media/audio/voice-samples/trump.wav"),
(HANASHI_USER_TOKEN, "m_g6dpwcpq51e6kvmpbbkdvgxfan9k1k", MediaFileType::Wav, "media/audio/voice-samples/trump_tts.wav"),
// Images
(HANASHI_USER_TOKEN, "m_cn5t6ywm9k1ge9qzzxst5krc5tm08m", MediaFileType::Jpg, "media/image/face-animator-inputs/bill.jpg"),
(HANASHI_USER_TOKEN, "m_nf9xebrr8hd1bxkfy7src5k8nv2dzy", MediaFileType::Jpg, "media/image/face-animator-inputs/elon.jpg"),
@@ -48,18 +48,18 @@ pub async fn seed_media_files(mysql_pool: &Pool<MySql>, maybe_bucket_clients: Op
(HANASHI_USER_TOKEN, "m_we7mnzbd76g4yn19dm6m53er0pjvew", MediaFileType::Png, "media/image/face-animator-inputs/san.png"),
(HANASHI_USER_TOKEN, "m_wahwz92nxxfg0x42dw9fdrhwq30yk0", MediaFileType::Jpg, "media/image/face-animator-inputs/zelda.jpg"),
// Video
(HANASHI_USER_TOKEN, "m_gedarcfdkxx3zv8zz2wmwsnc1r8jbp", MediaFileType::Video, "media/video/storyteller-studio-renders/girl-rotating-room.mp4"),
(HANASHI_USER_TOKEN, "m_3s74yyd4jwrjdp17yx1694n29jv5gr", MediaFileType::Video, "media/video/storyteller-studio-renders/hanashi-run.mp4"),
(HANASHI_USER_TOKEN, "m_p6d64gm1wawz25bmdahfded3366b9f", MediaFileType::Video, "media/video/storyteller-studio-renders/mocap-kiss.mp4"),
(HANASHI_USER_TOKEN, "m_szp2c77z6je965k44vc22xn9432a88", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-mocap-girl.mp4"),
(HANASHI_USER_TOKEN, "m_mdwspz81zymw9hvmb1d3jm830t25xe", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-mocap-m.mp4"),
(HANASHI_USER_TOKEN, "m_prcs6xkm8phs5y4a2dfwemwjy6n6z3", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-girl.mp4"),
(HANASHI_USER_TOKEN, "m_5j889dzw08vn9pbrscx1sncff43ekp", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-jww.mp4"),
(HANASHI_USER_TOKEN, "m_fwm2w6wbssez274ayz6x8ta0h1a9qp", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-pascal.mp4"),
(HANASHI_USER_TOKEN, "m_yqqkrt2srep6a35xg78114jn9epwg1", MediaFileType::Video, "media/video/storyteller-studio-renders/rotating-run-pop.mp4"),
(HANASHI_USER_TOKEN, "m_m4r043kez14pm6vaamsecpz8fafh7g", MediaFileType::Video, "media/video/video-style-transfer/man-explaining.mp4"),
(HANASHI_USER_TOKEN, "m_81gq3hygqvrahg6ncxbtcpjap4f9nv", MediaFileType::Video, "media/video/video-style-transfer/woman-gradient-background.mp4"),
(HANASHI_USER_TOKEN, "m_dp9ykj3yasjx69g2fx2bpd26wwjz0f", MediaFileType::Video, "media/video/video-style-transfer/woman-red-hair.mp4"),
(HANASHI_USER_TOKEN, "m_gedarcfdkxx3zv8zz2wmwsnc1r8jbp", MediaFileType::Mp4, "media/video/storyteller-studio-renders/girl-rotating-room.mp4"),
(HANASHI_USER_TOKEN, "m_3s74yyd4jwrjdp17yx1694n29jv5gr", MediaFileType::Mp4, "media/video/storyteller-studio-renders/hanashi-run.mp4"),
(HANASHI_USER_TOKEN, "m_p6d64gm1wawz25bmdahfded3366b9f", MediaFileType::Mp4, "media/video/storyteller-studio-renders/mocap-kiss.mp4"),
(HANASHI_USER_TOKEN, "m_szp2c77z6je965k44vc22xn9432a88", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-mocap-girl.mp4"),
(HANASHI_USER_TOKEN, "m_mdwspz81zymw9hvmb1d3jm830t25xe", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-mocap-m.mp4"),
(HANASHI_USER_TOKEN, "m_prcs6xkm8phs5y4a2dfwemwjy6n6z3", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-girl.mp4"),
(HANASHI_USER_TOKEN, "m_5j889dzw08vn9pbrscx1sncff43ekp", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-jww.mp4"),
(HANASHI_USER_TOKEN, "m_fwm2w6wbssez274ayz6x8ta0h1a9qp", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-pascal.mp4"),
(HANASHI_USER_TOKEN, "m_yqqkrt2srep6a35xg78114jn9epwg1", MediaFileType::Mp4, "media/video/storyteller-studio-renders/rotating-run-pop.mp4"),
(HANASHI_USER_TOKEN, "m_m4r043kez14pm6vaamsecpz8fafh7g", MediaFileType::Mp4, "media/video/video-style-transfer/man-explaining.mp4"),
(HANASHI_USER_TOKEN, "m_81gq3hygqvrahg6ncxbtcpjap4f9nv", MediaFileType::Mp4, "media/video/video-style-transfer/woman-gradient-background.mp4"),
(HANASHI_USER_TOKEN, "m_dp9ykj3yasjx69g2fx2bpd26wwjz0f", MediaFileType::Mp4, "media/video/video-style-transfer/woman-red-hair.mp4"),
];
let seed_tool_data_root = get_seed_tool_data_root();
@@ -73,14 +73,14 @@ pub async fn main() -> AnyhowResult<()> {
match mimetype {
Some("audio/wav") |
Some("audio/x-wav") => {
media_file_type = MediaFileType::Video;
media_file_type = MediaFileType::Wav;
maybe_mime_type = Some("audio/wav");
maybe_public_bucket_prefix = Some("dev_upload_");
maybe_public_bucket_extension = Some(".wav");
}
Some("video/mp4") => {
media_file_type = MediaFileType::Video;
media_file_type = MediaFileType::Mp4;
maybe_mime_type = mimetype;
maybe_public_bucket_prefix = Some("dev_upload_");
maybe_public_bucket_extension = Some(".mp4");
@@ -82,6 +82,10 @@ pub async fn insert_media_file_from_comfy_ui(args: InsertArgs<'_>) -> AnyhowResu
let maybe_model_type = args.maybe_model_type.map(|m| m.to_str());
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Video); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -129,7 +133,7 @@ SET
result_token.as_str(),
MediaFileClass::Video.to_str(),
MediaFileType::Video.to_str(), // TODO(bt,2024-04-30): This needs to become "mp4" after a frontend migration
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
product.to_str(),
@@ -69,6 +69,10 @@ pub async fn insert_media_file_from_f5_tts(
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::TextToSpeech;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Audio); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -116,7 +120,7 @@ SET
result_token.as_str(),
MediaFileClass::Audio.to_str(),
MediaFileType::Audio.to_str(), // TODO(bt,2024-04-30): This needs to become "wav" after a frontend migration
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
@@ -68,6 +68,10 @@ pub async fn insert_media_file_from_face_animation(
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::FaceAnimator;
const ORIGIN_MODEL_TYPE : MediaFileOriginModelType = MediaFileOriginModelType::SadTalker;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Video); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -108,7 +112,7 @@ SET
result_token.as_str(),
MediaFileClass::Video.to_str(),
MediaFileType::Video.to_str(),
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
@@ -66,7 +66,9 @@ pub async fn insert_media_file_from_rerender(
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::VideoFilter;
const ORIGIN_MODEL_TYPE : MediaFileOriginModelType = MediaFileOriginModelType::Rerender;
const MEDIA_TYPE : MediaFileType = MediaFileType::Video;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Video); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
@@ -109,7 +111,7 @@ SET
ORIGIN_PRODUCT_CATEGORY.to_str(),
ORIGIN_MODEL_TYPE.to_str(),
MEDIA_TYPE.to_str(),
media_type.to_str(),
args.maybe_mime_type,
args.file_size_bytes,
@@ -69,6 +69,10 @@ pub async fn insert_media_file_from_seed_vc(
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::TextToSpeech;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Audio); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -116,7 +120,7 @@ SET
result_token.as_str(),
MediaFileClass::Audio.to_str(),
MediaFileType::Audio.to_str(), // TODO(bt,2024-04-30): This needs to become "wav" after a frontend migration
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
@@ -75,6 +75,10 @@ pub async fn insert_media_file_from_studio_gen2(args: InsertArgs<'_>) -> AnyhowR
const MODEL_TYPE : MediaFileOriginModelType = MediaFileOriginModelType::StorytellerStudio;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Video); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -121,7 +125,7 @@ SET
result_token.as_str(),
MediaFileClass::Video.to_str(),
MediaFileType::Video.to_str(), // TODO(bt,2024-04-30): This needs to become "mp4" after a frontend migration
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
PRODUCT.to_str(),
@@ -69,6 +69,10 @@ pub async fn insert_media_file_from_tacotron2(
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::TextToSpeech;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Audio); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -116,7 +120,7 @@ SET
result_token.as_str(),
MediaFileClass::Audio.to_str(),
MediaFileType::Audio.to_str(), // TODO(bt,2024-04-30): This needs to become "wav" after a frontend migration
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
@@ -80,6 +80,10 @@ pub async fn insert_media_file_from_voice_conversion(
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::VoiceConversion;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Audio); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
r#"
@@ -122,7 +126,7 @@ SET
result_token.as_str(),
MediaFileClass::Audio.to_str(),
MediaFileType::Audio.to_str(), // TODO(bt,2024-04-30): This needs to become "wav" after a frontend migration
media_type.to_str(),
ORIGIN_CATEGORY.to_str(),
ORIGIN_PRODUCT_CATEGORY.to_str(),
@@ -70,7 +70,9 @@ pub async fn insert_media_file_from_zero_shot(
// Since fill this out apart of the funtion this seems like the only thing to change.
const ORIGIN_CATEGORY : MediaFileOriginCategory = MediaFileOriginCategory::Inference;
const ORIGIN_PRODUCT_CATEGORY : MediaFileOriginProductCategory = MediaFileOriginProductCategory::ZeroShotVoice;
const MEDIA_TYPE : MediaFileType = MediaFileType::Audio;
let media_type = args.maybe_mime_type
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Audio); // Coarse fallback for unrecognized mimes
let record_id = {
let query_result = sqlx::query!(
@@ -118,7 +120,7 @@ pub async fn insert_media_file_from_zero_shot(
args.job.maybe_raw_inference_text,
MEDIA_TYPE.to_str(),
media_type.to_str(),
args.maybe_mime_type,
args.file_size_bytes,
@@ -183,9 +183,18 @@ impl RawUserBookmarkRecord {
MediaFileType::Jpg => Some("image media file".to_string()),
MediaFileType::Png => Some("image media file".to_string()),
MediaFileType::Gif => Some("image media file".to_string()),
MediaFileType::Webp => Some("image media file".to_string()),
MediaFileType::Mp4 => Some("video media file".to_string()),
MediaFileType::Webm => Some("video media file".to_string()),
MediaFileType::Mov => Some("video media file".to_string()),
MediaFileType::Wav => Some("audio media file".to_string()),
MediaFileType::Mp3 => Some("audio media file".to_string()),
MediaFileType::Opus => Some("audio media file".to_string()),
MediaFileType::Ogg => Some("audio media file".to_string()),
MediaFileType::Aac => Some("audio media file".to_string()),
MediaFileType::M4a => Some("audio media file".to_string()),
MediaFileType::Flac => Some("audio media file".to_string()),
MediaFileType::Json => Some("project file".to_string()),
}),
UserBookmarkEntityType::VoiceConversionModel => self.maybe_descriptive_text_voice_conversion_model_title,
UserBookmarkEntityType::ZsVoice => self.maybe_descriptive_text_zs_voice_title,
@@ -90,6 +90,36 @@ pub enum MediaFileType {
/// Mp3 audio
Mp3,
// ========================= LESS SUPPORT FOR THE FILES BELOW THIS LINE ========================= //
/// Webp images
Webp,
/// Webm videos
Webm,
/// QuickTime videos
Mov,
/// Opus audio
Opus,
/// Ogg audio
Ogg,
/// AAC audio
Aac,
/// M4a audio
M4a,
/// FLAC audio
Flac,
/// Generic JSON documents (eg. internal project files).
/// NB: 3D scene files predate this and use `scene_json` instead.
Json,
}
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
@@ -110,6 +140,11 @@ impl MediaFileType {
pub fn is_jpg_or_png_or_legacy_image(&self) -> bool {
matches!(self, Self::Jpg | Self::Png | Self::Image)
}
/// Any image format, including the legacy coarse `Image` type.
pub fn is_image(&self) -> bool {
matches!(self, Self::Image | Self::Jpg | Self::Png | Self::Gif | Self::Webp)
}
/// Returns the `MediaFileType` if the mime type matches one of the known types.
/// This is not exhaustive.
@@ -119,15 +154,29 @@ impl MediaFileType {
match mime_type {
"image/jpeg" => Some(Self::Jpg),
"image/png" => Some(Self::Png),
"image/gif" => Some(Self::Gif),
"image/webp" => Some(Self::Webp),
"video/mp4" => Some(Self::Mp4),
"video/webm" => Some(Self::Webm),
"video/quicktime" => Some(Self::Mov),
"audio/wav" => Some(Self::Wav),
"audio/x-wav" => Some(Self::Wav),
"audio/wave" => Some(Self::Wav),
"audio/mpeg" => Some(Self::Mp3),
"audio/mp3" => Some(Self::Mp3),
"audio/opus" => Some(Self::Opus),
"audio/ogg" => Some(Self::Ogg),
"audio/aac" => Some(Self::Aac),
"audio/m4a" => Some(Self::M4a),
"audio/x-m4a" => Some(Self::M4a),
"audio/mp4" => Some(Self::M4a),
"audio/flac" => Some(Self::Flac),
"audio/x-flac" => Some(Self::Flac),
"model/gltf-binary" => Some(Self::Glb),
"model/gltf+json" => Some(Self::Gltf),
"model/fbx" => Some(Self::Fbx),
"application/fbx" => Some(Self::Fbx),
"model/obj" => Some(Self::Obj),
//"audio/wav" => Some(Self::Wav), // NB: Not sure if this is correct
//"audio/mpeg" => Some(Self::Mp3), // NB: Not sure if this is correct
//"image/gif" => Some(Self::Gif), // NB: Not sure if this is correct
//"model/gltf+json" => Some(Self::Gltf), // NB: Not sure if this is correct
_ => None,
}
}
@@ -155,6 +204,15 @@ impl MediaFileType {
Self::Mp4 => "mp4",
Self::Wav => "wav",
Self::Mp3 => "mp3",
Self::Webp => "webp",
Self::Webm => "webm",
Self::Mov => "mov",
Self::Opus => "opus",
Self::Ogg => "ogg",
Self::Aac => "aac",
Self::M4a => "m4a",
Self::Flac => "flac",
Self::Json => "json",
}
}
@@ -181,6 +239,15 @@ impl MediaFileType {
"mp4" => Ok(Self::Mp4),
"wav" => Ok(Self::Wav),
"mp3" => Ok(Self::Mp3),
"webp" => Ok(Self::Webp),
"webm" => Ok(Self::Webm),
"mov" => Ok(Self::Mov),
"opus" => Ok(Self::Opus),
"ogg" => Ok(Self::Ogg),
"aac" => Ok(Self::Aac),
"m4a" => Ok(Self::M4a),
"flac" => Ok(Self::Flac),
"json" => Ok(Self::Json),
_ => Err(format!("invalid value: {:?}", value)),
}
}
@@ -210,6 +277,15 @@ impl MediaFileType {
Self::Mp4,
Self::Wav,
Self::Mp3,
Self::Webp,
Self::Webm,
Self::Mov,
Self::Opus,
Self::Ogg,
Self::Aac,
Self::M4a,
Self::Flac,
Self::Json,
])
}
}
@@ -268,6 +344,15 @@ mod tests {
assert_serialization(MediaFileType::Mp4, "mp4");
assert_serialization(MediaFileType::Wav, "wav");
assert_serialization(MediaFileType::Mp3, "mp3");
assert_serialization(MediaFileType::Webp, "webp");
assert_serialization(MediaFileType::Webm, "webm");
assert_serialization(MediaFileType::Mov, "mov");
assert_serialization(MediaFileType::Opus, "opus");
assert_serialization(MediaFileType::Ogg, "ogg");
assert_serialization(MediaFileType::Aac, "aac");
assert_serialization(MediaFileType::M4a, "m4a");
assert_serialization(MediaFileType::Flac, "flac");
assert_serialization(MediaFileType::Json, "json");
}
}
@@ -296,6 +381,15 @@ mod tests {
assert_eq!(MediaFileType::Mp4.to_str(), "mp4");
assert_eq!(MediaFileType::Wav.to_str(), "wav");
assert_eq!(MediaFileType::Mp3.to_str(), "mp3");
assert_eq!(MediaFileType::Webp.to_str(), "webp");
assert_eq!(MediaFileType::Webm.to_str(), "webm");
assert_eq!(MediaFileType::Mov.to_str(), "mov");
assert_eq!(MediaFileType::Opus.to_str(), "opus");
assert_eq!(MediaFileType::Ogg.to_str(), "ogg");
assert_eq!(MediaFileType::Aac.to_str(), "aac");
assert_eq!(MediaFileType::M4a.to_str(), "m4a");
assert_eq!(MediaFileType::Flac.to_str(), "flac");
assert_eq!(MediaFileType::Json.to_str(), "json");
}
#[test]
@@ -320,6 +414,15 @@ mod tests {
assert_eq!(MediaFileType::from_str("mp4").unwrap(), MediaFileType::Mp4);
assert_eq!(MediaFileType::from_str("wav").unwrap(), MediaFileType::Wav);
assert_eq!(MediaFileType::from_str("mp3").unwrap(), MediaFileType::Mp3);
assert_eq!(MediaFileType::from_str("webp").unwrap(), MediaFileType::Webp);
assert_eq!(MediaFileType::from_str("webm").unwrap(), MediaFileType::Webm);
assert_eq!(MediaFileType::from_str("mov").unwrap(), MediaFileType::Mov);
assert_eq!(MediaFileType::from_str("opus").unwrap(), MediaFileType::Opus);
assert_eq!(MediaFileType::from_str("ogg").unwrap(), MediaFileType::Ogg);
assert_eq!(MediaFileType::from_str("aac").unwrap(), MediaFileType::Aac);
assert_eq!(MediaFileType::from_str("m4a").unwrap(), MediaFileType::M4a);
assert_eq!(MediaFileType::from_str("flac").unwrap(), MediaFileType::Flac);
assert_eq!(MediaFileType::from_str("json").unwrap(), MediaFileType::Json);
assert!(MediaFileType::from_str("foo").is_err());
}
}
@@ -330,7 +433,7 @@ mod tests {
#[test]
fn all_variants() {
let mut variants = MediaFileType::all_variants();
assert_eq!(variants.len(), 21);
assert_eq!(variants.len(), 30);
assert_eq!(variants.pop_first(), Some(MediaFileType::Audio));
assert_eq!(variants.pop_first(), Some(MediaFileType::Image));
assert_eq!(variants.pop_first(), Some(MediaFileType::Video));
@@ -352,6 +455,15 @@ mod tests {
assert_eq!(variants.pop_first(), Some(MediaFileType::Mp4));
assert_eq!(variants.pop_first(), Some(MediaFileType::Wav));
assert_eq!(variants.pop_first(), Some(MediaFileType::Mp3));
assert_eq!(variants.pop_first(), Some(MediaFileType::Webp));
assert_eq!(variants.pop_first(), Some(MediaFileType::Webm));
assert_eq!(variants.pop_first(), Some(MediaFileType::Mov));
assert_eq!(variants.pop_first(), Some(MediaFileType::Opus));
assert_eq!(variants.pop_first(), Some(MediaFileType::Ogg));
assert_eq!(variants.pop_first(), Some(MediaFileType::Aac));
assert_eq!(variants.pop_first(), Some(MediaFileType::M4a));
assert_eq!(variants.pop_first(), Some(MediaFileType::Flac));
assert_eq!(variants.pop_first(), Some(MediaFileType::Json));
assert_eq!(variants.pop_first(), None);
}
}
@@ -251,13 +251,8 @@ pub async fn process_job_inference(
}
};
let media_type = match metadata.mimetype.as_ref() {
"image/png" => MediaFileType::Png,
"image/jpeg" => MediaFileType::Jpg,
"image/gif" => MediaFileType::Gif,
"image/webp" => MediaFileType::Image, // Fallback
_ => MediaFileType::Image, // Fallback
};
let media_type = MediaFileType::try_from_mime_type(metadata.mimetype.as_ref())
.unwrap_or(MediaFileType::Image); // Coarse fallback for unrecognized mimes
// extra_file_modification_info: todo!(), // JSON ENCODED STRUCT
let (media_file_token, _id) = insert_media_file_generic_from_job(InsertFromJobArgs {
@@ -257,7 +257,9 @@ pub async fn process_job(args: BvhToWorkflowJobArgs<'_>) -> Result<JobSuccessRes
pool: &args.job_dependencies.db.mysql_pool,
job: &job,
media_class: MediaFileClass::Video,
media_type: MediaFileType::Video,
media_type: maybe_mimetype.as_deref()
.and_then(MediaFileType::try_from_mime_type)
.unwrap_or(MediaFileType::Video), // Coarse fallback for unrecognized mimes
origin_category: MediaFileOriginCategory::Processed,
origin_product_category: MediaFileOriginProductCategory::Mocap,
maybe_origin_model_type: None,
@@ -177,26 +177,9 @@ pub async fn process_upload_media_file(
// do not have any open issues filed. They may simply be too old:
// - .wma (audio/x-ms-wma)
// - .avi (video/x-msvideo)
media_file_type = match mimetype {
// Audio
"audio/aac" /* .aac */ => Some(MediaFileType::Audio),
"audio/m4a" /* .m4a */ => Some(MediaFileType::Audio),
"audio/mpeg" /* .mp3 */ => Some(MediaFileType::Audio),
"audio/ogg" /* .ogg */ => Some(MediaFileType::Audio),
"audio/opus" /* .opus */ => Some(MediaFileType::Audio),
"audio/x-flac" /* .flac */ => Some(MediaFileType::Audio),
"audio/x-wav" /* .wav */ => Some(MediaFileType::Audio),
// Image — `webp` has no dedicated variant yet
"image/gif" /* .gif */ => Some(MediaFileType::Gif),
"image/jpeg" /* .jpg */ => Some(MediaFileType::Jpg),
"image/png" /* .png */ => Some(MediaFileType::Png),
"image/webp" /* .webp */ => Some(MediaFileType::Image), // TODO: Replace.
// Video
"video/mp4" /* .mp4 */ => Some(MediaFileType::Video),
"video/quicktime" /* .mov */ => Some(MediaFileType::Video),
"video/webm" /* .webm */ => Some(MediaFileType::Video),
_ => None,
};
// NB: mimetypes are gated by the allow-list check above; this only maps
// the already-permitted set to concrete media types.
media_file_type = MediaFileType::try_from_mime_type(mimetype);
let do_audio_decode = match mimetype {
// TODO: Revisit when Safari can send us this metadata consistently
@@ -236,13 +236,8 @@ pub async fn upload_snapshot_media_file_handler(
MediaFileUploadError::ServerError
})?;
let media_file_type = match mimetype.as_str() {
"image/jpeg" => MediaFileType::Jpg,
"image/png" => MediaFileType::Png,
"image/gif" => MediaFileType::Gif,
"image/webp" => MediaFileType::Image, // Fallback
_ => MediaFileType::Image, // Fallback
};
let media_file_type = MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Image); // Coarse fallback for unrecognized mimes
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Image),
@@ -129,9 +129,9 @@ pub async fn set_media_file_cover_image_handler(
//let can_use_image = media_file.creator_set_visibility == Visibility::Public
// && media_file.media_type == MediaFileType::Image;
let can_use_image = media_file.media_type == MediaFileType::Image;
let can_use_image = media_file.media_type.is_image();
if !can_use_image {
if !can_use_image {
return Err(CommonWebError::BadInputWithSimpleMessage("Invalid media file token.".to_string()));
}
@@ -333,7 +333,8 @@ pub async fn upload_audio_media_file_handler(
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Audio),
media_file_type: MediaFileType::Audio,
media_file_type: MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Audio), // Coarse fallback for unrecognized mimes
maybe_creator_user_token: maybe_user_token,
maybe_creator_anonymous_visitor_token: maybe_avt_token.as_ref(),
creator_ip_address: &ip_address,
@@ -204,26 +204,9 @@ pub async fn process_upload_media_file(
// do not have any open issues filed. They may simply be too old:
// - .wma (audio/x-ms-wma)
// - .avi (video/x-msvideo)
media_file_type = match mimetype {
// Audio
"audio/aac" /* .aac */ => Some(MediaFileType::Audio),
"audio/m4a" /* .m4a */ => Some(MediaFileType::Audio),
"audio/mpeg" /* .mp3 */ => Some(MediaFileType::Audio),
"audio/ogg" /* .ogg */ => Some(MediaFileType::Audio),
"audio/opus" /* .opus */ => Some(MediaFileType::Audio),
"audio/x-flac" /* .flac */ => Some(MediaFileType::Audio),
"audio/x-wav" /* .wav */ => Some(MediaFileType::Audio),
// Image — `webp` has no dedicated variant yet
"image/gif" /* .gif */ => Some(MediaFileType::Gif),
"image/jpeg" /* .jpg */ => Some(MediaFileType::Jpg),
"image/png" /* .png */ => Some(MediaFileType::Png),
"image/webp" /* .webp */ => Some(MediaFileType::Image),
// Video
"video/mp4" /* .mp4 */ => Some(MediaFileType::Video),
"video/quicktime" /* .mov */ => Some(MediaFileType::Video),
"video/webm" /* .webm */ => Some(MediaFileType::Video),
_ => None,
};
// NB: mimetypes are gated by the `allowed_mimetypes` check above; this only
// maps the already-permitted set to concrete media types.
media_file_type = MediaFileType::try_from_mime_type(mimetype);
let do_audio_decode = match mimetype {
// TODO: Revisit when Safari can send us this metadata consistently
@@ -332,9 +315,18 @@ pub async fn process_upload_media_file(
MediaFileType::Jpg => MediaFileClass::Image,
MediaFileType::Png => MediaFileClass::Image,
MediaFileType::Gif => MediaFileClass::Image,
MediaFileType::Webp => MediaFileClass::Image,
MediaFileType::Mp4 => MediaFileClass::Video,
MediaFileType::Webm => MediaFileClass::Video,
MediaFileType::Mov => MediaFileClass::Video,
MediaFileType::Wav => MediaFileClass::Audio,
MediaFileType::Mp3 => MediaFileClass::Audio,
MediaFileType::Opus => MediaFileClass::Audio,
MediaFileType::Ogg => MediaFileClass::Audio,
MediaFileType::Aac => MediaFileClass::Audio,
MediaFileType::M4a => MediaFileClass::Audio,
MediaFileType::Flac => MediaFileClass::Audio,
MediaFileType::Json => MediaFileClass::Unknown,
};
let upload_type = match upload_media_request.media_source {
@@ -299,13 +299,8 @@ pub async fn upload_image_media_file_handler(
UploadType::Filesystem
};
let media_file_type = match mimetype.as_str() {
"image/jpeg" => MediaFileType::Jpg,
"image/png" => MediaFileType::Png,
"image/gif" => MediaFileType::Gif,
"image/webp" => MediaFileType::Image, // Fallback
_ => MediaFileType::Image, // fallback
};
let media_file_type = MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Image); // Coarse fallback for unrecognized mimes
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Image),
@@ -506,7 +506,8 @@ pub async fn upload_new_video_media_file_handler(
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Video),
media_file_type: MediaFileType::Video,
media_file_type: MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Video), // Coarse fallback for unrecognized mimes
maybe_creator_user_token: maybe_user_token,
maybe_creator_anonymous_visitor_token: maybe_avt_token.as_ref(),
creator_ip_address: &ip_address,
@@ -221,7 +221,8 @@ pub async fn upload_video_media_file_handler(
// TODO(bt, 2024-02-22): This should be a transaction.
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Video),
media_file_type: MediaFileType::Video,
media_file_type: MediaFileType::try_from_mime_type(mimetype)
.unwrap_or(MediaFileType::Video), // Coarse fallback for unrecognized mimes
maybe_creator_user_token: maybe_user_token,
maybe_creator_anonymous_visitor_token: maybe_avt_token.as_ref(),
creator_ip_address: &ip_address,
@@ -202,15 +202,12 @@ impl MediaUploadKind {
}
fn media_file_type(&self, mimetype: &str) -> MediaFileType {
match self {
MediaUploadKind::Image => match mimetype {
"image/jpeg" => MediaFileType::Jpg,
"image/png" => MediaFileType::Png,
"image/gif" => MediaFileType::Gif,
_ => MediaFileType::Image,
},
MediaUploadKind::Video => MediaFileType::Video,
MediaUploadKind::Audio => MediaFileType::Audio,
}
MediaFileType::try_from_mime_type(mimetype)
.unwrap_or(match self {
// Coarse fallbacks for unrecognized mimes
MediaUploadKind::Image => MediaFileType::Image,
MediaUploadKind::Video => MediaFileType::Video,
MediaUploadKind::Audio => MediaFileType::Audio,
})
}
}
@@ -277,7 +277,8 @@ pub async fn omni_upload_audio_media_file_handler(
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Audio),
media_file_type: MediaFileType::Audio,
media_file_type: MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Audio), // Coarse fallback for unrecognized mimes
maybe_creator_user_token: maybe_user_token,
// NB: AVT (anonymous visitor) tokens are a web-session concept; API-key callers have none.
maybe_creator_anonymous_visitor_token: None,
@@ -259,13 +259,8 @@ pub async fn omni_upload_image_media_file_handler(
UploadType::Filesystem
};
let media_file_type = match mimetype.as_str() {
"image/jpeg" => MediaFileType::Jpg,
"image/png" => MediaFileType::Png,
"image/gif" => MediaFileType::Gif,
"image/webp" => MediaFileType::Image, // Fallback
_ => MediaFileType::Image, // fallback
};
let media_file_type = MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Image); // Coarse fallback for unrecognized mimes
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Image),
@@ -458,7 +458,8 @@ pub async fn omni_upload_video_media_file_handler(
let (token, record_id) = insert_media_file_from_file_upload(InsertMediaFileFromUploadArgs {
maybe_media_class: Some(MediaFileClass::Video),
media_file_type: MediaFileType::Video,
media_file_type: MediaFileType::try_from_mime_type(&mimetype)
.unwrap_or(MediaFileType::Video), // Coarse fallback for unrecognized mimes
maybe_creator_user_token: maybe_user_token,
// NB: AVT (anonymous visitor) tokens are a web-session concept; API-key callers have none.
maybe_creator_anonymous_visitor_token: None,
@@ -134,9 +134,9 @@ pub async fn set_model_weight_cover_image_handler(
//let can_use_image = media_file.creator_set_visibility == Visibility::Public
// && media_file.media_type == MediaFileType::Image;
let can_use_image = media_file.media_type == MediaFileType::Image;
let can_use_image = media_file.media_type.is_image();
if !can_use_image {
if !can_use_image {
return Err(CommonWebError::BadInputWithSimpleMessage("Invalid media file token.".to_string()));
}
@@ -158,7 +158,7 @@ pub async fn update_weight_handler(
let maybe_media_file_type = maybe_media_file.map(|media_file| media_file.media_type);
match maybe_media_file_type {
Some(MediaFileType::Image) => cover_image = Some(CoverImageOption::SetCoverImage(media_file_token)),
Some(media_file_type) if media_file_type.is_image() => cover_image = Some(CoverImageOption::SetCoverImage(media_file_token)),
None => return Err(CommonWebError::BadInputWithSimpleMessage("Media file does not exist".to_string())),
_ => return Err(CommonWebError::BadInputWithSimpleMessage("Media file is the wrong type".to_string())),
}