Search code examples
xpageslotus-noteswatson

Writing a binary response (stream) directly to MIME in a Notes document


As I'm playing around with the Watson API I am using the Text2Speech service to get an audio stream (file) from the service. I already get the file with the code but my MIME doesn't contain anything later. I save the document after I call this method below. Any best pratices for streaming a byte content directly to a MIME would be appreciated.

public void getSpeechFromText(AveedoContext aveedoContext, Document doc, String fieldName, String text, String voiceName) {
    try {
        Session session = aveedoContext.getXspHelper().getSession();
        session.setConvertMIME(false);
        TextToSpeech service = new TextToSpeech();
        String username = watsonSettings.getTextToSpeechUsername();
        String password = watsonSettings.getTextToSpeechPassword();
        if (username.isEmpty() || password.isEmpty()) {
            throw new AveedoException("No credentials provided for service");
        }
        service.setUsernameAndPassword(username, password);
        MIMEEntity mime = doc.getMIMEEntity(fieldName);
        if (mime == null) {
            mime = doc.createMIMEEntity(fieldName);
        }

        // local proxy?
        if (!Util.isEmpty(customEndpoint)) {
            // service.setEndPoint(customEndpoint + "/speech/");
        }

        Voice voice = Voice.getByName(voiceName);
        AudioFormat audio = AudioFormat.WAV;

        System.out.println("Fieldname: " + fieldName + "SPEECH: " + text + ", Voice: " + voice.getName() + ", Format: "
                + audio.toString());

        InputStream stream = service.synthesize(text, voice, audio).execute();
        InputStream in = WaveUtils.reWriteWaveHeader(stream);

        Stream out = session.createStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = in.read(buffer)) > 0) {
            out.write(buffer);
        }
        mime.setContentFromBytes(out, "audio/wav", MIMEEntity.ENC_IDENTITY_BINARY);
        out.close();            
        session.setConvertMIME(true);
        in.close();
        stream.close();

    } catch (Throwable e) {
        aveedoLogger.error("Error calling Watson service (text to speech)", e);
        e.printStackTrace();
    }
}

Solution

  • I believe that you need to create a child MIME entity. I use the following code in one of my apps to attach an image:

    boolean convertMime = JSFUtil.getSessionAsSigner().isConvertMime();
    if (convertMime) {
        JSFUtil.getSessionAsSigner().setConvertMime(false);
    }
    
    final MIMEEntity body = doc.createMIMEEntity(getAttachmentFieldName());
    
    // Add binary attachment
    final MIMEEntity attachmentChild = body.createChildEntity();
    final MIMEHeader bodyHeader = attachmentChild.createHeader("Content-Disposition");
    bodyHeader.setHeaderVal("attachment; filename=" + incident.getPhoto().getName());
    Stream imgStream = getPhoto(doc, incident.getPhoto());
    attachmentChild.setContentFromBytes(imgStream, incident.getPhoto().getType(), MIMEEntity.ENC_IDENTITY_BINARY);
    imgStream.close();
    imgStream.recycle();
    imgStream = null;
    
    if (convertMime) {
        JSFUtil.getSessionAsSigner().setConvertMime(true);
    }