Class chuyển nội dung bài viết thành giọng đọc file audio mp3

Lại Đình Cường

Tài liệu thiết kế website

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.

0 0 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest
0 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất