Class bên dưới sẽ mô tả cách chuyển nội dung bài viết thành giọng đọc (Text to Speech, Content to Speech).
<?php
defined( 'ABSPATH' ) || exit;
class CTS_Text_To_Speech {
public $api_key;
public $voice_id;
public $text;
public $error;
public $response;
private $voice;
public function __construct( $api_key, $voice_id, $text ) {
$this->set_api_key( $api_key );
$this->set_voice_id( $voice_id );
$this->set_text( $text );
$this->error = new WP_Error();
}
public function get_voice() {
$voices = $this->get_voice_ids();
$this->sanitize_voices_response( $voices );
if ( is_array( $voices ) ) {
foreach ( $voices as $voice ) {
if ( is_object( $voice ) && isset( $voice->voice_id ) && $this->voice_id == $voice->voice_id ) {
$this->voice = $voice;
break;
}
}
}
return $this->voice;
}
public function get_voice_ids() {
$tr_name = 'elevenlabs_voice_ids';
if ( false === ( $res = get_transient( $tr_name ) ) ) {
$url = 'https://api.elevenlabs.io/v1/voices';
$res = wp_remote_retrieve_body( wp_remote_get( $url ) );
if ( ! empty( $res ) ) {
$res = json_decode( $res );
$this->sanitize_voices_response( $res );
set_transient( $tr_name, $res );
}
}
return $res;
}
public function set_api_key( $api_key ) {
$this->api_key = $api_key;
}
private function sanitize_voices_response( &$res ) {
if ( is_object( $res ) && isset( $res->voices ) ) {
$res = $res->voices;
}
}
public function set_voice_id( $voice_id ) {
if ( empty( $voice_id ) || 'rand' == $voice_id || 'random' == $voice_id ) {
$voices = $this->get_voice_ids();
$this->sanitize_voices_response( $voices );
if ( is_array( $voices ) ) {
shuffle( $voices );
foreach ( $voices as $obj ) {
if ( is_object( $obj ) && isset( $obj->voice_id ) ) {
$voice_id = $obj->voice_id;
break;
}
}
}
}
$this->voice_id = $voice_id;
}
public function set_text( $text ) {
$this->text = $text;
}
public function get_base_url() {
return 'https://api.elevenlabs.io/v1/text-to-speech/' . $this->voice_id;
}
public function calculate_timeout() {
$count = str_word_count( strip_tags( $this->text ) );
$count = ceil( $count / 150 );
if ( $count < MINUTE_IN_SECONDS ) {
$count = MINUTE_IN_SECONDS;
}
return $count;
}
public function generate( $type = 'remote' ) {
if ( 'curl' == $type ) {
$this->response = $this->curl();
} else {
$this->response = $this->remote();
}
if ( is_string( $this->response ) && str_contains( $this->response, 'detail' ) ) {
$res = json_decode( $this->response );
if ( is_object( $res ) && isset( $res->detail ) ) {
$this->response = '';
if ( is_object( $res->detail ) && isset( $res->detail->status ) ) {
$this->error->add( $res->detail->status, $res->detail->message );
} else {
$this->error->add( 'response_detail', $res->detail );
}
}
}
return $this->response;
}
private function build_body() {
return wp_json_encode( array(
'text' => $this->text
) );
}
private function build_header() {
return array(
'Content-Type' => 'application/json',
'xi-api-key' => $this->api_key
);
}
private function remote() {
$args = array(
'timeout' => $this->calculate_timeout(),
'headers' => $this->build_header(),
'body' => $this->build_body()
);
$res = wp_remote_post( $this->get_base_url(), $args );
if ( is_wp_error( $res ) ) {
$this->error->merge_from( $res );
}
return wp_remote_retrieve_body( $res );
}
private function curl() {
$curl = curl_init();
$headers = $this->build_header();
$header = array();
foreach ( $headers as $key => $value ) {
$header[] = $key . ': ' . $value;
}
curl_setopt_array( $curl, [
CURLOPT_URL => $this->get_base_url(),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => $this->calculate_timeout(),
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $this->build_body(),
CURLOPT_HTTPHEADER => $header
] );
$response = curl_exec( $curl );
$err = curl_error( $curl );
curl_close( $curl );
if ( $err ) {
$this->error->add( 'curl_error', $err );
}
return $response;
}
}
Đoạn code ví dụ bên trên sử dụng API của ElevenLabs. Gói miễn phí được sử dụng 10.000 ký tự mỗi tháng.