Я пытаюсь отправить записанное аудио из веб-браузера на Oracle Apex, но возникает проблема, когда звук достаточно длинный. Код работает очень хорошо, когда аудио менее двух минут.
Что я знаю, данные отправляются по URL, поэтому они отправляются в текстовом формате. Oracle имеет ограничение в 32 КБ для строки, поэтому, если большой двоичный объект превышает этот предел, его необходимо отправить в массиве, разделенном на части по 30 КБ каждая. Поэтому я подозреваю, что массив отправляется не в правильном формате, но я не знаю, как это подтвердить.
Я использую следующий код: (Я создал плагин для Apex для отправить аудио)
- Фрагмент в Javascript, который отправляет аудио:
// builds a js array from long string
clob2Array: function(clob, size, array) {
loopCount = Math.floor(clob.length / size) + 1;
for (var i = 0; i < loopCount; i++) {
array.push(clob.slice(size * i, size * (i + 1)));
}
return array;
},
// converts DataURI to base64 string
dataURI2base64: function(dataURI) {
var base64 = dataURI.substr(dataURI.indexOf(',') + 1);
return base64;
},
blobToDataURL: function(blob, callback) {
var a = new FileReader();
a.onload = function(e) {callback(e.target.result);}
a.readAsDataURL(blob);
},
// save to DB function
save2Db: function(pAjaxIdentifier, pRegionId, pAudio, callback) {
apexAudio.blobToDataURL(pAudio, function(data){
// audio DataURI to base64
var base64 = apexAudio.dataURI2base64(data);
// split base64 clob string to f01 array length 30k
var f01Array = new Array();
f01Array = apexAudio.clob2Array(base64, 30000, f01Array);
// Apex Ajax Call
apex.server.plugin(pAjaxIdentifier, {
f01: f01Array,
}, {
dataType: 'html',
// SUCESS function
success: function() {
// add apex event
$('#' + pRegionId).trigger('apexaudio-saved-db');
// callback
callback();
},
// ERROR function
error: function(xhr, pMessage) {
// add apex event
$('#' + pRegionId).trigger('apexaudio-error-db');
console.log('save2Db: apex.server.plugin ERROR:', pMessage);
// callback
callback();
}
});
});
}
- Код PL / SQL, который получает adn, преобразует массив строк в blob
DECLARE
--
l_collection_name VARCHAR2(100);
l_blob BLOB;
l_filename VARCHAR2(100);
l_mime_type VARCHAR2(100);
l_token VARCHAR2(32000);
--
BEGIN
-- get defaults
l_filename := 'audio_' || to_char(SYSDATE, 'YYYYMMDDHH24MISS') || '.webm';
l_mime_type := 'audio/webm';
-- build BLOB from f01 30k Array
dbms_lob.createtemporary(l_blob,
TRUE,
dbms_lob.session);
FOR i IN 1 .. apex_application.g_f01.count LOOP
l_token := wwv_flow.g_f01(i);
IF length(l_token) > 0 THEN
dbms_lob.append(l_blob
,to_blob(utl_encode.base64_decode(utl_raw.cast_to_raw(l_token))));
END IF;
END LOOP;
l_collection_name := 'APEX_AUDIO';
APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION(
p_collection_name => l_collection_name);
-- add collection member (only if BLOB not null)
IF dbms_lob.getlength(l_blob) IS NOT NULL THEN
apex_collection.add_member(p_collection_name => l_collection_name,
p_c001 => l_filename, -- filename
p_c002 => l_mime_type, -- mime_type
p_d001 => SYSDATE, -- date created
p_blob001 => l_blob); -- BLOB audio content
END IF;
END;
Повторяю, код работает отлично, если звук короткий, но если он длинный, возникает следующая ошибка:
2020-02-20T20:09:27.169Z SEVERE <P-fvMwI2WpKybDySZRumRQ> java.sql.SQLException: ORA-06550: line 2, column 2:
PLS-00306: number or wrong type arguments when calling 'AJAX'
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
InternalServerException [statusCode=500, reasons=[]]
at oracle.dbtools.apex.ModApexContext.handleError(ModApexContext.java:288)
at oracle.dbtools.apex.OWA.execute(OWA.java:206)
at oracle.dbtools.apex.ModApex.handleRequest(ModApex.java:310)
at oracle.dbtools.apex.ModApex.doPost(ModApex.java:188)
at oracle.dbtools.apex.ModApex.service(ModApex.java:112)
at oracle.dbtools.http.entrypoint.Dispatcher.dispatch(Dispatcher.java:126)
[...]
Технология :
- Oracle 12 c
- Oracle Apex 19,2
- Ords 19,4
- Tomcat 8