Skip to content

Commit

Permalink
upd
Browse files Browse the repository at this point in the history
Create README.md

PHP_EOL

change package type

1.0.0

Update README.md

fix composer
  • Loading branch information
421p committed Sep 23, 2018
1 parent 2310b85 commit f518038
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 8 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Talker
Text to speech using Google TTS

## Installing

```
composer require 421p/talker
```

## Usage

```php
use React\EventLoop\Factory;
use Talker\Talker\GoogleSpeechTalker;
use Talker\Talker\Response\Mp3File;

require __DIR__.'/vendor/autoload.php';

$loop = Factory::create();

$talker = new GoogleSpeechTalker($loop);

[$hours, $minutes] = explode(':', date('H:i'));

$time = sprintf(
'Current time is %d hours %d minutes', $hours, $minutes
);

$talker->say($time, GoogleSpeechTalker::LOCALE_EN_US)->then(function (Mp3File $file) {
file_put_contents(__DIR__.'/test.mp3', $file->getContent());
});

$loop->run();
```
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"name": "421p/talker",
"version" : "1.0.0",
"description": "PHP Text to speech",
"type": "project",
"type": "library",
"minimum-stability": "dev",
"license": "MIT",
"authors": [
{
Expand All @@ -15,6 +17,7 @@
}
},
"require": {
"php": ">=7.1",
"react/http-client": "^0.5.9"
},
"require-dev": {
Expand Down
106 changes: 105 additions & 1 deletion src/Talker/GoogleSpeechTalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,111 @@
namespace Talker\Talker;


class GoogleSpeechTalker
use React\EventLoop\LoopInterface;
use React\HttpClient\Client;
use React\HttpClient\Response;
use React\Promise\Deferred;
use React\Promise\PromiseInterface;
use Talker\Talker\Response\ResourceMp3File;

class GoogleSpeechTalker implements TalkerInterface
{
public const LOCALE_EN_GB = 'en_gb';
public const LOCALE_EN_AU = 'en_au';
public const LOCALE_EN_US = 'en_us';
public const LOCALE_RU = 'ru';

private const BASE_URL = 'http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=%s&tl=%s';

/**
* @var LoopInterface
*/
private $loop;

private $client;

public function __construct(LoopInterface $loop)
{
$this->loop = $loop;

$this->client = new Client($loop);
}

/**
* @param string $text
*
* @param string $locale
*
* @return PromiseInterface
*/
public function say(string $text, string $locale): PromiseInterface
{
$defer = new Deferred();

$promises = [];

foreach (explode(PHP_EOL, wordwrap($text, 100)) as $chunk) {
$promises[] = $this->doRequest($chunk, $locale);
}

\React\Promise\all($promises)->then(
function (array $files) use ($defer) {

$resultStream = fopen('php://memory', 'rw');

/** @var ResourceMp3File $file */
foreach ($files as $file) {
stream_copy_to_stream($file->getStream(), $resultStream);
}

rewind($resultStream);

$defer->resolve(new ResourceMp3File($resultStream));
}
);

return $defer->promise();
}

private function doRequest(string $text, string $locale): PromiseInterface
{
$defer = new Deferred();

$request = $this->client->request(
'GET',
$this->getRequestUrl(urlencode($text), $locale)
);

$request->on(
'response',
function (Response $response) use ($defer) {
$stream = fopen('php://memory', 'rw');

$response->on(
'data',
function ($chunk) use ($stream) {
fwrite($stream, $chunk);
}
);

$response->on(
'end',
function () use ($stream, $defer) {
rewind($stream);

$defer->resolve(new ResourceMp3File($stream));
}
);
}
);

$request->end();

return $defer->promise();
}

private function getRequestUrl(string $text, string $locale)
{
return sprintf(self::BASE_URL, $text, $locale);
}
}
4 changes: 2 additions & 2 deletions src/Talker/Response/AudioFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Talker\Talker\Response;


class AudioFile
interface AudioFile
{

public function getContent(): string;
}
2 changes: 1 addition & 1 deletion src/Talker/Response/Mp3File.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Talker\Talker\Response;


class Mp3File
interface Mp3File extends AudioFile
{

}
29 changes: 28 additions & 1 deletion src/Talker/Response/ResourceMp3File.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,34 @@
namespace Talker\Talker\Response;


class ResourceMp3File
class ResourceMp3File implements Mp3File
{
private $stream;

public function __construct($stream)
{
$this->stream = $stream;
}

public function __destruct()
{
fclose($this->stream);
}

public function getContent(): string
{
$data = stream_get_contents($this->stream);

rewind($this->stream);

return $data;
}

/**
* @return mixed
*/
public function getStream()
{
return $this->stream;
}
}
13 changes: 11 additions & 2 deletions src/Talker/TalkerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@
namespace Talker\Talker;


class TailerInterface
{
use React\Promise\PromiseInterface;

interface TalkerInterface
{
/**
* @param string $text
*
* @param string $locale
*
* @return PromiseInterface
*/
public function say(string $text, string $locale): PromiseInterface;
}

0 comments on commit f518038

Please sign in to comment.