fix: wav format audio, #2317
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Tooltip, Upload } from 'antd';
|
||||
import { Button, Tooltip, Upload, message } from 'antd';
|
||||
import React from 'react';
|
||||
import { convertFileSize } from '../../utils';
|
||||
|
||||
interface UploadAudioProps {
|
||||
accept?: string;
|
||||
@@ -10,17 +11,36 @@ interface UploadAudioProps {
|
||||
icon?: React.ReactNode;
|
||||
size?: 'small' | 'middle' | 'large';
|
||||
shape?: 'circle' | 'round' | 'default';
|
||||
maxFileSize?: number; // in bytes
|
||||
onChange?: (data: { file: any; fileList: any[] }) => void;
|
||||
}
|
||||
|
||||
const UploadAudio: React.FC<UploadAudioProps> = (props) => {
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const { icon, accept, type, size = 'large', shape = 'circle' } = props;
|
||||
const intl = useIntl();
|
||||
const beforeUpload = (file: any) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const isFileSizeValid = (file: File) => {
|
||||
if (props.maxFileSize && file.size > props.maxFileSize) {
|
||||
messageApi.open({
|
||||
type: 'warning',
|
||||
content: intl.formatMessage(
|
||||
{ id: 'playground.uploadfile.sizeError' },
|
||||
{ size: `${convertFileSize(props.maxFileSize)}` } // Convert bytes to MB
|
||||
)
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleOnChange = (data: { file: any; fileList: any }) => {
|
||||
if (!isFileSizeValid(data.file)) {
|
||||
return;
|
||||
}
|
||||
props.onChange?.(data);
|
||||
};
|
||||
|
||||
@@ -57,6 +77,7 @@ const UploadAudio: React.FC<UploadAudioProps> = (props) => {
|
||||
></Button>
|
||||
</div>
|
||||
</Upload>
|
||||
{contextHolder}
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -154,5 +154,7 @@ export default {
|
||||
'If the expected model isn’t showing up, make sure it’s running and correctly categorized. If the category is incorrect, you can manually adjust it in the model’s settings.',
|
||||
'playground.rerank.query.validate': 'The query is required.',
|
||||
'playground.image.generate.error':
|
||||
'Something went wrong. The image could not be generated.'
|
||||
'Something went wrong. The image could not be generated.',
|
||||
'playground.uploadfile.sizeError':
|
||||
'File size exceeds the limit. Maximum allowed: {size}.'
|
||||
};
|
||||
|
||||
@@ -157,10 +157,13 @@ export default {
|
||||
'期待するモデルが表示されない場合は、モデルが実行中で正しく分類されていることを確認してください。カテゴリが間違っている場合は、モデルの設定で手動で調整できます。',
|
||||
'playground.rerank.query.validate': 'The query is required.',
|
||||
'playground.image.generate.error':
|
||||
'Something went wrong. The image could not be generated.'
|
||||
'Something went wrong. The image could not be generated.',
|
||||
'playground.uploadfile.sizeError':
|
||||
'File size exceeds the limit. Maximum allowed: {size}.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'playground.rerank.query.validate': 'The query is required.'
|
||||
// 2. 'playground.image.generate.error': 'Something went wrong. The image could not be generated.'
|
||||
// 2. 'playground.image.generate.error': 'Something went wrong. The image could not be generated.',
|
||||
// 3. 'playground.uploadfile.sizeError': 'File size exceeds the limit. Maximum allowed: {size}.'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -151,10 +151,13 @@ export default {
|
||||
'Если нужная модель не отображается, убедитесь, что она запущена и ей присвоена правильная категория. Если категория указана неверно, её можно изменить вручную в настройках модели.',
|
||||
'playground.rerank.query.validate': 'The query is required.',
|
||||
'playground.image.generate.error':
|
||||
'Something went wrong. The image could not be generated.'
|
||||
'Something went wrong. The image could not be generated.',
|
||||
'playground.uploadfile.sizeError':
|
||||
'File size exceeds the limit. Maximum allowed: {size}.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'playground.rerank.query.validate': 'The query is required.'
|
||||
// 2. 'playground.image.generate.error': 'Something went wrong. The image could not be generated.'
|
||||
// 2. 'playground.image.generate.error': 'Something went wrong. The image could not be generated.',
|
||||
// 3. 'playground.uploadfile.sizeError': 'File size exceeds the limit. Maximum allowed: {size}.'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -147,5 +147,6 @@ export default {
|
||||
'playground.model.noavailable.tips2':
|
||||
'若预期的模型未显示,请检查模型是否已正常运行并被正确分类。如分类不正确,请编辑模型并手动调整其类别。',
|
||||
'playground.rerank.query.validate': '查询内容不能为空',
|
||||
'playground.image.generate.error': '出了一点问题,图片未能生成。'
|
||||
'playground.image.generate.error': '出了一点问题,图片未能生成。',
|
||||
'playground.uploadfile.sizeError': '上传的文件大小超过限制,最大允许 {size}'
|
||||
};
|
||||
|
||||
@@ -2,7 +2,11 @@ import SimpleAudio from '@/components/audio-player/simple-audio';
|
||||
import IconFont from '@/components/icon-font';
|
||||
import UploadAudio from '@/components/upload-audio';
|
||||
import HotKeys, { KeyMap } from '@/config/hotkeys';
|
||||
import { convertFileToBase64, readAudioFile } from '@/utils/load-audio-file';
|
||||
import {
|
||||
audioTypeMap,
|
||||
convertFileToBase64,
|
||||
readAudioFile
|
||||
} from '@/utils/load-audio-file';
|
||||
import {
|
||||
ClearOutlined,
|
||||
CustomerServiceOutlined,
|
||||
@@ -28,12 +32,6 @@ import '../style/message-input.less';
|
||||
import ThumbImg from './thumb-img';
|
||||
import UploadImg from './upload-img';
|
||||
|
||||
const audioTypeMap: Record<string, string> = {
|
||||
'audio/wav': 'wav',
|
||||
'audio/mp3': 'mp3',
|
||||
'audio/mpeg': 'mp3'
|
||||
};
|
||||
|
||||
const AudioWrapper = styled.div`
|
||||
padding-block: 10px;
|
||||
height: max-content;
|
||||
@@ -303,7 +301,7 @@ const MessageInput: React.FC<MessageInputProps> = forwardRef(
|
||||
try {
|
||||
const base64Audio = await convertFileToBase64(data.file);
|
||||
const audioData = await readAudioFile(data.file);
|
||||
console.log('audioData====', message.imgs);
|
||||
console.log('audioData====', audioData, message.imgs);
|
||||
setMessage((pre) => {
|
||||
return {
|
||||
...pre,
|
||||
@@ -421,6 +419,7 @@ const MessageInput: React.FC<MessageInputProps> = forwardRef(
|
||||
)}
|
||||
{actions.includes('upload') && message.role === Roles.User && (
|
||||
<UploadAudio
|
||||
maxFileSize={1024 * 1024}
|
||||
type="text"
|
||||
accept={'.mp3,.wav'}
|
||||
size="middle"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import CopyButton from '@/components/copy-button';
|
||||
import UploadAudio from '@/components/upload-audio';
|
||||
import { convertFileToBase64, readAudioFile } from '@/utils/load-audio-file';
|
||||
import {
|
||||
audioTypeMap,
|
||||
convertFileToBase64,
|
||||
readAudioFile
|
||||
} from '@/utils/load-audio-file';
|
||||
import {
|
||||
CustomerServiceOutlined,
|
||||
EditOutlined,
|
||||
@@ -18,12 +22,6 @@ import {
|
||||
} from '../../config/types';
|
||||
import UploadImg from '../upload-img';
|
||||
|
||||
const audioTypeMap: Record<string, string> = {
|
||||
'audio/wav': 'wav',
|
||||
'audio/mp3': 'mp3',
|
||||
'audio/mpeg': 'mp3'
|
||||
};
|
||||
|
||||
interface MessageActionsProps {
|
||||
data: MessageItem;
|
||||
actions: MessageItemAction[];
|
||||
@@ -88,6 +86,7 @@ const MessageActions: React.FC<MessageActionsProps> = ({
|
||||
{actions.includes('upload') && data.role === Roles.User && (
|
||||
<UploadAudio
|
||||
type="text"
|
||||
maxFileSize={1024 * 1024}
|
||||
accept={'.mp3,.wav'}
|
||||
size="small"
|
||||
shape="default"
|
||||
|
||||
+4
-2
@@ -28,12 +28,14 @@ export const convertFileSize = (
|
||||
): string | number => {
|
||||
if (!sizeInBytes) return allowEmpty ? '' : 0;
|
||||
|
||||
const fmt = 1024;
|
||||
|
||||
const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
|
||||
let size = sizeInBytes;
|
||||
let unitIndex = 0;
|
||||
|
||||
while (size >= 1024 && unitIndex < units.length - 1) {
|
||||
size /= 1024;
|
||||
while (size >= fmt && unitIndex < units.length - 1) {
|
||||
size /= fmt;
|
||||
unitIndex++;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { message } from 'antd';
|
||||
import { convertFileSize } from './index';
|
||||
|
||||
export const audioTypeMap: Record<string, string> = {
|
||||
'audio/wav': 'wav',
|
||||
'audio/mp3': 'mp3',
|
||||
'audio/mpeg': 'mp3',
|
||||
'audio/x-wav': 'wav'
|
||||
};
|
||||
|
||||
export const convertFileToBase64 = (file: File): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
@@ -42,6 +50,12 @@ export const loadAudioData = async (
|
||||
audio.addEventListener('ended', () => {
|
||||
URL.revokeObjectURL(audio.src);
|
||||
});
|
||||
|
||||
audio.addEventListener('error', () => {
|
||||
URL.revokeObjectURL(url);
|
||||
message.error('Failed to load audio metadata invalid file');
|
||||
reject(new Error('Failed to load audio metadata invalid file'));
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('error====', error);
|
||||
reject(error);
|
||||
|
||||
Reference in New Issue
Block a user