Issues (7)

src/Converters/PollyConverter.php (3 issues)

1
<?php
2
3
namespace Cion\TextToSpeech\Converters;
4
5
use Aws\Polly\PollyClient;
6
use Aws\Result;
7
use Cion\TextToSpeech\Contracts\Converter;
8
use Cion\TextToSpeech\Traits\HasLanguage;
9
use Cion\TextToSpeech\Traits\Sourceable;
10
use Cion\TextToSpeech\Traits\SSMLable;
11
use Cion\TextToSpeech\Traits\Storable;
12
use Illuminate\Support\Arr;
13
14
class PollyConverter implements Converter
15
{
16
    use Storable, Sourceable, HasLanguage, SSMLable;
17
18
    /**
19
     * Client instance of Polly.
20
     *
21
     * @var \Aws\Polly\PollyClient
22
     */
23
    protected $client;
24
25
    /**
26
     * Construct converter.
27
     *
28
     * @param PollyClient $client
29
     */
30
    public function __construct(PollyClient $client)
31
    {
32
        $this->client = $client;
33
    }
34
35
    /**
36
     * Get the Polly Client.
37
     *
38
     * @return \Aws\Polly\PollyClient
39
     */
40
    public function getClient(): PollyClient
41
    {
42
        return $this->client;
43
    }
44
45
    /**
46
     * Converts the text to speech.
47
     *
48
     * @param string $data
49
     * @param array $options
50
     * @return string
51
     */
52
    public function convert(string $data, array $options = null)
53
    {
54
        $text = $this->getTextFromSource($data);
55
56
        if ($this->isTextAboveLimit($text)) {
57
            $text = $this->getChunkText($text);
58
        }
59
60
        $result = $this->synthesizeSpeech($text, $options);
61
62
        if ($result instanceof Result) {
63
            // Store audio file to disk
64
            return $this->store(
65
                $this->getTextFromSource($data),
66
                $this->getResultContent($result)
67
            );
68
        }
69
70
        return $this->store(
71
            $this->getTextFromSource($data),
72
            $this->mergeOutputs($result)
73
        );
74
    }
75
76
    /**
77
     * Request to Amazon Polly to synthesize speech.
78
     *
79
     * @param string|array $text
80
     * @param array $options
81
     * @return array|\Aws\Result
82
     */
83
    protected function synthesizeSpeech($text, array $options = null)
84
    {
85
        if (is_string($text)) {
86
            return $this->client->synthesizeSpeech([
87
                'LanguageCode' => $this->getLanguage(),
88
                'VoiceId'      => $this->voice($options),
89
                'OutputFormat' => $this->format($options),
90
                'TextType'     => $this->textType(),
0 ignored issues
show
Are you sure the usage of $this->textType() targeting Cion\TextToSpeech\Conver...lyConverter::textType() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
91
                'Text'         => $text,
92
            ]);
93
        }
94
95
        $results = [];
96
97
        foreach ($text as $textItem) {
98
            $result = $this->client->synthesizeSpeech([
99
                'LanguageCode' => $this->getLanguage(),
100
                'VoiceId'      => $this->voice($options),
101
                'OutputFormat' => $this->format($options),
102
                'TextType'     => $this->textType(),
0 ignored issues
show
Are you sure the usage of $this->textType() targeting Cion\TextToSpeech\Conver...lyConverter::textType() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
103
                'Text'         => $textItem,
104
            ]);
105
106
            array_push($results, $result);
107
        }
108
109
        return $results;
110
    }
111
112
    /**
113
     * Merges the output from amazon polly.
114
     *
115
     * @return mixed
116
     */
117
    protected function mergeOutputs(array $results)
118
    {
119
        $mergedResult = null;
120
        foreach ($results as $result) {
121
            $mergedResult .= $this->getResultContent($result);
122
        }
123
124
        return $mergedResult;
125
    }
126
127
    /**
128
     * Checks the length of the text if more than 3000.
129
     *
130
     * @param string $text
131
     * @return bool
132
     */
133
    protected function isTextAboveLimit(string $text)
134
    {
135
        return strlen($text) > 2000;
136
    }
137
138
    /**
139
     * Chunk the given text into array.
140
     *
141
     * @param string $text
142
     * @param int $size
143
     * @return array
144
     */
145
    protected function getChunkText(string $text, int $size = 2000)
146
    {
147
        return explode("\n", wordwrap($text, $size));
148
    }
149
150
    /**
151
     * Get the text to speech voice ID.
152
     *
153
     * @param  array $options
154
     * @return string
155
     */
156
    protected function voice($options)
157
    {
158
        $default = config('tts.services.polly.voice_id', 'Amy');
159
160
        return Arr::get($options, 'voice', $default);
161
    }
162
163
    /**
164
     * Get the text type.
165
     *
166
     * @return void
167
     */
168
    protected function textType()
169
    {
170
        $default = config('tts.text_type', 'text');
171
172
        return $this->textType ?? $default;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->textType ?? $default also could return the type string which is incompatible with the documented return type void.
Loading history...
173
    }
174
175
    /**
176
     * Get the language.
177
     *
178
     * @return string
179
     */
180
    protected function getLanguage()
181
    {
182
        return $this->language ?? config('tts.language', 'en-US');
183
    }
184
185
    /**
186
     * Get the audio format.
187
     *
188
     * @param  array $options
189
     * @return string
190
     */
191
    protected function format($options)
192
    {
193
        $default = config('tts.output_format', 'mp3');
194
195
        return Arr::get($options, 'format', $default);
196
    }
197
198
    /**
199
     * Get the content of the result from AWS Polly.
200
     *
201
     * @param mixed $result
202
     * @return mixed
203
     */
204
    protected function getResultContent($result)
205
    {
206
        return $result->get('AudioStream')->getContents();
207
    }
208
}
209