Skip to content

Commit

Permalink
Update commmands
Browse files Browse the repository at this point in the history
Yurujai committed Mar 8, 2024
1 parent fd27e14 commit df3770f
Showing 9 changed files with 49 additions and 155 deletions.
5 changes: 0 additions & 5 deletions .idea/.gitignore

This file was deleted.

10 changes: 0 additions & 10 deletions .idea/PumukitYoutubeBundle.iml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

22 changes: 0 additions & 22 deletions .idea/php.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

140 changes: 45 additions & 95 deletions Command/DownloadVideosFromYouTubeChannel.php
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
use Doctrine\ODM\MongoDB\DocumentManager;
use Pumukit\EncoderBundle\Document\Job;
use Pumukit\SchemaBundle\Document\MultimediaObject;
use Pumukit\SchemaBundle\Document\Series;
use Pumukit\SchemaBundle\Document\Tag;
use Pumukit\YoutubeBundle\Services\GoogleAccountService;
use Symfony\Component\Console\Command\Command;
@@ -27,6 +28,7 @@ final class DownloadVideosFromYouTubeChannel extends Command
private DocumentManager $documentManager;
private GoogleAccountService $googleAccountService;
private string $tempDir;
private array $youtubeErrors = [];

public function __construct(DocumentManager $documentManager, GoogleAccountService $googleAccountService, string $tempDir)
{
@@ -40,24 +42,9 @@ protected function configure(): void
{
$this
->setName('pumukit:youtube:download:videos:from:channel')
->addOption(
'account',
null,
InputOption::VALUE_REQUIRED,
'Account'
)
->addOption(
'channel',
null,
InputOption::VALUE_REQUIRED,
'Channel ID'
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
'limit'
)
->addOption('account', null, InputOption::VALUE_REQUIRED, 'Account')
->addOption('channel', null, InputOption::VALUE_REQUIRED, 'Channel ID')
->addOption('limit', null, InputOption::VALUE_OPTIONAL, 'limit')
->setDescription('Import all videos from Youtube channel')
->setHelp(
<<<'EOT'
@@ -76,75 +63,61 @@ protected function configure(): void
protected function execute(InputInterface $input, OutputInterface $output): int
{
$channel = $input->getOption('channel');
$limit = (int) $input->getOption('limit');

$youtubeAccount = $this->ensureYouTubeAccountExists($input);

$service = $this->googleAccountService->googleServiceFromAccount($youtubeAccount);
$channelId = $this->channelId($channel, $service);
$multimediaObjects = $this->documentManager->getRepository(MultimediaObject::class)->findBy([
'status' => ['$in' => [MultimediaObject::STATUS_PUBLISHED, MultimediaObject::STATUS_HIDDEN]],
'properties.youtube_import_status' => ['$exists' => false],
'properties.youtube_import_channel' => $channel,
], [], $limit ?? null);

$nextPageToken = null;
$count = 0;
$queryParams = [
'type' => 'video',
'forMine' => true,
'maxResults' => 50,
];

$response = $service->search->listSearch('snippet', $queryParams);

$progressBar = new ProgressBar($output, $response->pageInfo->getTotalResults());
$progressBar = new ProgressBar($output, count($multimediaObjects));
$progressBar->start();

do {
$count = 0;
foreach($multimediaObjects as $multimediaObject) {
$progressBar->advance();
if (null !== $input->getOption('limit') && $count >= $input->getOption('limit')) {
break;
}
$count++;

if (null !== $nextPageToken) {
$queryParams['pageToken'] = $nextPageToken;
$videoId = $multimediaObject->getProperty('youtube_import_id');
$youtubeDownloader = new YouTubeDownloader();

$youtubeURL = self::BASE_URL_YOUTUBE_VIDEO.$videoId;
$downloadOptions = $youtubeDownloader->getDownloadLinks($youtubeURL);

if (empty($downloadOptions->getAllFormats())) {
$multimediaObject->setProperty('youtube_download_info', json_encode($downloadOptions));
$this->documentManager->flush();

$this->youtubeErrors[] = 'URL: '.$youtubeURL.' no formats found. Formats: '.json_encode($downloadOptions->getAllFormats());

continue;
}

$service = $this->googleAccountService->googleServiceFromAccount($youtubeAccount);
$response = $service->search->listSearch('snippet', $queryParams);
$nextPageToken = $response->getNextPageToken();

foreach ($response->getItems() as $item) {
$progressBar->advance();
if (null !== $input->getOption('limit') && $count >= $input->getOption('limit')) {
break;
}
++$count;
$videoId = $item->getId()->getVideoId();
$youtubeDownloader = new YouTubeDownloader();

try {
$youtubeURL = self::BASE_URL_YOUTUBE_VIDEO.$videoId;
$downloadOptions = $youtubeDownloader->getDownloadLinks($youtubeURL);

if (empty($downloadOptions->getAllFormats())) {
$output->writeln('URL: '.$youtubeURL.' no formats found.');

continue;
}

$url = $this->selectBestStreamFormat($downloadOptions);

try {
$this->moveFileToStorage($item, $url, $downloadOptions, $channelId);
} catch (\Exception $exception) {
$output->writeln('Error moving file to storage: '.$exception->getMessage());
}
} catch (YouTubeException $e) {
$output->writeln('There was error downloaded video with title '.$item->snippet->title.' and id '.$videoId);

continue;
}
$url = $this->selectBestStreamFormat($downloadOptions);

try {
$this->moveFileToStorage($multimediaObject, $url, $downloadOptions, $channel);
$multimediaObject->setProperty('youtube_import_status', 'downloaded');
$this->documentManager->flush();
} catch (\Exception $exception) {
$this->youtubeErrors[] = 'Error moving file to storage: '.$exception->getMessage();
continue;
}
} while (null !== $nextPageToken);
}

$progressBar->finish();
$output->writeln(' ');

foreach ($this->youtubeErrors as $error) {
$output->writeln($error);
}

return 0;
}

@@ -201,26 +174,13 @@ private function selectBestStreamFormat(DownloadOptions $downloadOptions): ?Stre
return null;
}

private function moveFileToStorage($item, $url, DownloadOptions $downloadOptions, string $channelId): void
private function moveFileToStorage(MultimediaObject $multimediaObject, $url, DownloadOptions $downloadOptions, string $channelId): void
{
$videoId = $item->getId()->getVideoId();
$videoId = $multimediaObject->getProperty('youtube_import_id');
$mimeType = explode('video/', $this->selectBestStreamFormat($downloadOptions)->getCleanMimeType())[1];
$this->createChannelDir($channelId);
$file = $this->tempDir.'/'.$channelId.'/'.$videoId.'.'.$mimeType;

$multimediaObject = $this->documentManager->getRepository(MultimediaObject::class)->findOneBy([
'properties.youtube_import_id' => $videoId,
]);

$failedJobs = $this->documentManager->getRepository(Job::class)->findOneBy([
'status' => Job::STATUS_ERROR,
'mm_id' => $multimediaObject,
]);

if (!file_exists($file) && $multimediaObject instanceof MultimediaObject && !$failedJobs instanceof Job) {
return;
}

$content = file_get_contents($url->url);

file_put_contents($file, $content);
@@ -246,14 +206,4 @@ private function ensureYouTubeAccountExists(InputInterface $input): Tag
return $youtubeAccount;
}

private function channelId(string $channel, \Google_Service_YouTube $service): string
{
$queryParams = [
'id' => $channel,
];

$channels = $service->channels->listChannels('snippet', $queryParams);

return $channels->getItems()[0]->getId();
}
}
7 changes: 1 addition & 6 deletions Command/ImportVideosFromYouTubeChannel.php
Original file line number Diff line number Diff line change
@@ -78,7 +78,6 @@ protected function configure(): void
->addOption('account', null, InputOption::VALUE_REQUIRED, 'Account')
->addOption('channel', null, InputOption::VALUE_REQUIRED, 'Channel ID')
->addOption('limit', null, InputOption::VALUE_OPTIONAL, 'limit')
->addOption('live', null, InputOption::VALUE_OPTIONAL, 'Import lives instead of videos')
->setDescription('Import all videos from Youtube channel')
->setHelp(
<<<'EOT'
@@ -87,11 +86,7 @@ protected function configure(): void
Limit is optional to test the command.
Usage: php bin/console pumukit:youtube:import:videos:from:channel --account={ACCOUNT} --channel={CHANNEL_ID} --limit={LIMIT} --live
To import live instead of videos use --live param
Usage: php bin/console pumukit:youtube:import:videos:from:channel --account={ACCOUNT} --channel={CHANNEL_ID} --limit={LIMIT} --live
Usage: php bin/console pumukit:youtube:import:videos:from:channel --account={ACCOUNT} --channel={CHANNEL_ID} --limit={LIMIT}

EOT
)
4 changes: 2 additions & 2 deletions Resources/doc/ImportFromYoutube.md
Original file line number Diff line number Diff line change
@@ -15,9 +15,9 @@ where ACCOUNT is the name added for YouTube tag created on PuMuKIT and CHANNEL_I

### 2. Import videos from YouTube

Before download videos you will be able to import videos from YouTube to PuMuKIT using this command.
Import videos metadata from YouTube

The command will be autocomplete metadata from YouTube and create a new video on PuMuKIT and move the video to the series created on step 1.
The command creates a new video on PuMuKIT for each video on YouTube and move it to the series created on step 1.

```
php bin/console pumukit:youtube:import:videos:from:channel --account={ACCOUNT} --channel={CHANNEL_ID}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
}
],
"require": {
"php": "^7.4 || ^8.2",
"php": "^8.2",
"pumukit/pumukit": ">4.0",
"google/apiclient" : "^2.0",
"athlon1600/youtube-downloader": "^4.0"

0 comments on commit df3770f

Please sign in to comment.