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

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.

5/5 - (1 bình chọn)

Lại Đình Cường

Tôi làm quen và phát triển WordPress từ năm 2008, cho đến nay thì đã có hơn 13 năm kinh nghiệm, thật không thể tin được. Tôi có đam mê và dành nhiều thời gian làm việc với WordPress mỗi ngày, hiện tại tôi đang phát triển giao diện và plugin cho WordPress.

Nếu bạn đang cần người làm trang web bằng WordPress? Hãy liên hệ với tôi ngay để được tư vấn nhé.