@@ -34,6 +34,7 @@ public function __construct( $feature_instance = null ) {
34
34
$ this ->feature_instance = $ feature_instance ;
35
35
36
36
do_action ( 'classifai_ ' . static ::ID . '_init ' , $ this );
37
+ add_action ( 'wp_ajax_classifai_get_voice_dropdown ' , [ $ this , 'get_voice_dropdown ' ] );
37
38
}
38
39
39
40
/**
@@ -107,7 +108,41 @@ public function render_provider_fields() {
107
108
]
108
109
);
109
110
110
- $ voices_options = $ this ->get_voices_select_options ();
111
+ add_settings_field (
112
+ 'voice_engine ' ,
113
+ esc_html__ ( 'Engine ' , 'classifai ' ),
114
+ [ $ this ->feature_instance , 'render_select ' ],
115
+ $ this ->feature_instance ->get_option_name (),
116
+ $ this ->feature_instance ->get_option_name () . '_section ' ,
117
+ [
118
+ 'option_index ' => static ::ID ,
119
+ 'label_for ' => 'voice_engine ' ,
120
+ 'options ' => array (
121
+ 'standard ' => esc_html__ ( 'Standard ' , 'classifai ' ),
122
+ 'neural ' => esc_html__ ( 'Neural ' , 'classifai ' ),
123
+ 'long-form ' => esc_html__ ( 'Long Form ' , 'classifai ' ),
124
+ ),
125
+ 'default_value ' => $ settings ['voice_engine ' ],
126
+ 'class ' => 'classifai-provider-field hidden provider-scope- ' . static ::ID , // Important to add this.
127
+ 'description ' => sprintf (
128
+ wp_kses (
129
+ /* translators: %1$s is replaced with the OpenAI sign up URL */
130
+ __ ( 'Amazon Polly offers <a href="%1$s">Long-Form</a>, <a href="%2$s">Neural</a> and Standard text-to-speech voices. Please check the <a title="Pricing" href="%3$s">documentation</a> to review pricing for Long-Form, Neural and Standard usage. ' , 'classifai ' ),
131
+ [
132
+ 'a ' => [
133
+ 'href ' => [],
134
+ 'title ' => [],
135
+ ],
136
+ ]
137
+ ),
138
+ esc_url ( 'https://docs.aws.amazon.com/polly/latest/dg/long-form-voice-overview.html ' ),
139
+ esc_url ( 'https://docs.aws.amazon.com/polly/latest/dg/NTTS-main.html ' ),
140
+ esc_url ( 'https://aws.amazon.com/polly/pricing/ ' )
141
+ )
142
+ ]
143
+ );
144
+
145
+ $ voices_options = $ this ->get_voices_select_options ( $ settings ['voice_engine ' ] ?? '' );
111
146
if ( ! empty ( $ voices_options ) ) {
112
147
add_settings_field (
113
148
'voice ' ,
@@ -120,7 +155,7 @@ public function render_provider_fields() {
120
155
'label_for ' => 'voice ' ,
121
156
'options ' => $ voices_options ,
122
157
'default_value ' => $ settings ['voice ' ],
123
- 'class ' => 'classifai-provider-field hidden provider-scope- ' . static ::ID , // Important to add this.
158
+ 'class ' => 'classifai-aws-polly-voices classifai- provider-field hidden provider-scope- ' . static ::ID , // Important to add this.
124
159
]
125
160
);
126
161
}
@@ -253,7 +288,7 @@ public function connect_to_service( array $args = array() ): array {
253
288
*
254
289
* @return array
255
290
*/
256
- public function get_voices_select_options (): array {
291
+ public function get_voices_select_options ( string $ engine = "" ): array {
257
292
$ settings = $ this ->feature_instance ->get_settings ( static ::ID );
258
293
$ voices = $ settings ['voices ' ];
259
294
$ options = array ();
@@ -263,7 +298,14 @@ public function get_voices_select_options(): array {
263
298
}
264
299
265
300
foreach ( $ voices as $ voice ) {
266
- if ( ! is_array ( $ voice ) || empty ( $ voice ) ) {
301
+ if (
302
+ ! is_array ( $ voice ) ||
303
+ empty ( $ voice ) ||
304
+ (
305
+ ! empty ( $ engine ) &&
306
+ ! in_array ( $ engine , $ voice ['SupportedEngines ' ], true )
307
+ )
308
+ ) {
267
309
continue ;
268
310
}
269
311
@@ -322,15 +364,35 @@ public function synthesize_speech( int $post_id ) {
322
364
$ voice = $ settings [ static ::ID ]['voice ' ] ?? '' ;
323
365
324
366
try {
325
- $ polly_client = $ this ->get_polly_client ();
326
- $ result = $ polly_client ->synthesizeSpeech (
367
+ $ polly_client = $ this ->get_polly_client ();
368
+
369
+ /**
370
+ * Filter Synthesize speech args.
371
+ *
372
+ * @since 3.1.0
373
+ * @hook classifai_aws_polly_synthesize_speech_args
374
+ *
375
+ * @param {array} Associative array of synthesize speech args.
376
+ * @param {int} $post_id Post ID.
377
+ * @param {object} $provider_instance Provider instance.
378
+ * @param {object} $feature_instance Feature instance.
379
+ *
380
+ * @return {array} The filtered array of synthesize speech args.
381
+ */
382
+ $ synthesize_data = apply_filters (
383
+ 'classifai_ ' . self ::ID . '_synthesize_speech_args ' ,
327
384
array (
328
385
'OutputFormat ' => 'mp3 ' ,
329
386
'Text ' => $ post_content ,
330
387
'TextType ' => 'text ' ,
388
+ 'Engine ' => $ settings [ static ::ID ]['voice_engine ' ] ?? 'standard ' , // 'standard', 'neural', 'long-form'
331
389
'VoiceId ' => $ voice ,
332
- )
390
+ ),
391
+ $ post_id ,
392
+ $ this ,
393
+ $ this ->feature_instance
333
394
);
395
+ $ result = $ polly_client ->synthesizeSpeech ( $ synthesize_data );
334
396
335
397
update_post_meta ( $ post_id , self ::AUDIO_HASH_KEY , md5 ( $ post_content ) );
336
398
$ contents = $ result ['AudioStream ' ]->getContents ();
@@ -410,9 +472,9 @@ public function get_polly_client( array $aws_config = array() ) {
410
472
$ settings = $ this ->feature_instance ->get_settings ( static ::ID );
411
473
412
474
$ default = array (
413
- 'access_key_id ' => isset ( $ settings [ static :: ID ][ 'access_key_id ' ] ) ? $ settings[ static :: ID ] ['access_key_id ' ] : '' ,
414
- 'secret_access_key ' => isset ( $ settings [ static :: ID ][ 'secret_access_key ' ] ) ? $ settings[ static :: ID ] ['secret_access_key ' ] : '' ,
415
- 'aws_region ' => isset ( $ settings [ static :: ID ][ 'aws_region ' ] ) ? $ settings[ static :: ID ] ['aws_region ' ] : 'us-east-1 ' ,
475
+ 'access_key_id ' => isset ( $ settings ['access_key_id ' ] ) ? $ settings ['access_key_id ' ] : '' ,
476
+ 'secret_access_key ' => isset ( $ settings ['secret_access_key ' ] ) ? $ settings ['secret_access_key ' ] : '' ,
477
+ 'aws_region ' => isset ( $ settings ['aws_region ' ] ) ? $ settings ['aws_region ' ] : 'us-east-1 ' ,
416
478
);
417
479
418
480
$ default = wp_parse_args ( $ aws_config , $ default );
@@ -436,4 +498,44 @@ public function get_polly_client( array $aws_config = array() ) {
436
498
$ sdk = new \Aws \Sdk ($ aws_sdk_config );
437
499
return $ sdk ->createPolly ();
438
500
}
501
+
502
+ /**
503
+ * Returns the voice dropdown for the selected engine.
504
+ */
505
+ public function get_voice_dropdown () {
506
+ if ( ! wp_doing_ajax () ) {
507
+ return ;
508
+ }
509
+
510
+ // Nonce check.
511
+ if ( ! check_ajax_referer ( 'classifai ' , 'nonce ' , false ) ) {
512
+ $ error = new \WP_Error ( 'classifai_nonce_error ' , __ ( 'Nonce could not be verified. ' , 'classifai ' ) );
513
+ wp_send_json_error ( $ error );
514
+ exit ();
515
+ }
516
+
517
+ // Set the feature instance if it's not already set.
518
+ if ( ! $ this ->feature_instance instanceof TextToSpeech ) {
519
+ $ this ->feature_instance = new TextToSpeech ();
520
+ }
521
+
522
+ // Attachment ID check.
523
+ $ engine = isset ( $ _POST ['engine ' ] ) ? sanitize_text_field ( wp_unslash ( $ _POST ['engine ' ] ) ) : 'standard ' ;
524
+ $ settings = $ this ->feature_instance ->get_settings ( static ::ID );
525
+ $ voices_options = $ this ->get_voices_select_options ( $ engine );
526
+
527
+ ob_start ();
528
+ $ this ->feature_instance ->render_select (
529
+ [
530
+ 'option_index ' => static ::ID ,
531
+ 'label_for ' => 'voice ' ,
532
+ 'options ' => $ voices_options ,
533
+ 'default_value ' => $ settings ['voice ' ],
534
+ 'class ' => 'classifai-provider-field hidden provider-scope- ' . static ::ID , // Important to add this.
535
+ ]
536
+ );
537
+ $ voice_dropdown = ob_get_clean ();
538
+
539
+ wp_send_json_success ( $ voice_dropdown );
540
+ }
439
541
}
0 commit comments