@islam-404

Создать плейлист по условиям автоматический?

Пишу программу которая создает плейлист из видео по нескольким условиям.
1) По жанрам.
2) Каждый седьмой клип один из трех жанров, по очереди.
3) Артист не должен повторяться пока все остальные не будут в списке.

1) По жанрам:
У каждой песни(клип) есть свои теги жанра например
"01_LZ_LV_Айгуль Джумагулова_Суьюв мени бийлеген.mp4"
"LZ" тут и есть тег жанра.

2)Каждый седьмой клип один из трех жанров, по очереди:
["LZ", "MD", "BS", "MD", "LZ", "MD", ["AN", "DB", "KB"], "BS", "MD", "LZ", "MD", "BS", "MD", ["AN", "DR", "KB"]]
вот как должны идти песни по жанрам, а каждый седьмой клип сначала песня с тегом AN потом DB и последнее KB и начинать заново. Выглядеть это должно примерно так:
["LZ", "MD", "BS", "MD", "LZ", "MD", ["AN"], "BS", "MD", "LZ", "MD", "BS", "MD", ["DR"]]
["LZ", "MD", "BS", "MD", "LZ", "MD", ["KB"], "BS", "MD", "LZ", "MD", "BS", "MD", ["AN"]]
["LZ", "MD", "BS", "MD", "LZ", "MD", ["DR"], "BS", "MD", "LZ", "MD", "BS", "MD", ["KB"]]
В таком порядке должны идти клипы.

3) Артист не должен повторяться пока все остальные не будут в списке:
Как и жанр у каждого артиста есть свой ID это первые две цифры.
"01_LZ_LV_Айгуль Джумагулова_Суьюв мени бийлеген.mp4"
Тут это "01" а у последнего у меня это "99" , то есть у меня есть 99 разных певцов, а клипов почти 400

Сначала будет мой код на PHP потом в комментах результат и последнее это весь список, не знаю может кому то понадобится

$genres = ["LZ", "MD", "BS", "MD", "LZ", "MD", ["AN", "DB", "KB"], "BS", "MD", "LZ", "MD", "BS", "MD", ["AN", "DR", "KB"]];
    $idPlayer = 0;
    $incGenres = 0;
    $incGenresTwo = 0;
    $leng = 0;
    $l = 0;
    $playList = ["###"];
    $tempPlayList = ["###"];
    $temp = false;
    $tempTwo;
    $endFunc = 5000;


    function searchGenres($video, $genres, $inc)
    {
        global $playList, $idPlayer, $tempPlayList, $incGenresTwo, $tempTwo;
        $genre = $genres[$inc];
        if (is_array($genre)) {
            $tempTwo = $genre;
                if ($incGenresTwo == 3) {
                    $incGenresTwo = 0;
                }
                $genre = $genre[$incGenresTwo];
        }
        $arrVideo = explode('_', $video);
        for ($i = 0; $i < count($arrVideo); $i++) {
            $itemVideo = $arrVideo[$i];
            if ("$itemVideo" == "$genre") {
                $idPlayer = $arrVideo[0];
                array_push($playList, "$video");
                if (is_array($tempTwo)) {
                    $tempTwo = "";
                    $incGenresTwo++;
                
                }
                foreach ($tempPlayList as $key => $item) {
                    if ($item == $video) {
                        unset($tempPlayList[$key]);
                    }
                }
                return "$video";
            }
        }
    }


    function chekPlayList($video, $genres, $inc)
    {
        global $playList, $idPlayer;
        global $temp;
        $arrVideo = explode('_', $video);
        if ($idPlayer < $arrVideo[0]) {
        for ($i = 0; $i < count($playList); $i++) {
            if (strcasecmp($playList[$i], $video) == 0) {
                $temp = true;
            }
        }
        if ($temp == false) {
            return searchGenres($video, $genres, $inc);
        }
        }
    }

    function load()
    {
        global $temp, $l, $endFunc, $leng;
        global $incGenres, $incGenresTwo;
        global $genres, $genresTwo;
        global $tempPlayList;
        if ($handle = opendir('./one')) {
            while (false != ($entry = readdir($handle))) {
                if ($entry != "." && $entry != "..") {
                    array_push($tempPlayList, "$entry");
                }
            }
        }
        closedir($handle);
    }

    load();
    function play()
    {
        global $temp, $l, $endFunc, $leng, $idPlayer;
        global $incGenres, $incGenresTwo;
        global $genres, $genresTwo;
        global $tempPlayList;
        foreach ($tempPlayList as $nameVideo) {
            if ("$nameVideo" == "end.txt") {
                $idPlayer = -1;
                }

            if (is_string(chekPlayList($nameVideo, $genres, $incGenres))) {
                $temp = false;
                // $leng++;
                if ($incGenres == count($genres)) {
                    $incGenres = 0;
                } else {
                    $incGenres++;
                }
                play();
                return;
            } else {
                $temp = false;
                if ("$nameVideo" == "end.txt") {
                    // echo "<br> не нашел ", $genres[$incGenres], "<br>";
                    // $leng++;
                    if ($l == $endFunc) {
                        break;
                    }
                    $l++;
                    if ($incGenres == count($genres)) {
                        $incGenres = 0;
                    } else {
                        $incGenres++;
                    }
                    play();
                }
            }
        }
        unset($nameVideo);
    }

    play();
    echo "<pre>";
    print_r($playList);
    echo "</pre>";
    echo "<pre>";
    print_r($tempPlayList);
    echo "</pre>";


Проблема в том что каждый седьмой не песни нужными тегами(AN или DR или KB) еще номера актеров повторяются быстрее чем надо. Что я там делаю:
load(); - загружаю весь список в один массив
play(): - начинаю искать
далее написал бы, но тут и так много текста

Я уже не первый день вожусь с этим пожалуйста помогите, если где то в коде что то не понятно пишите я отвечу, если кто то захочет могу и по дискорд показать и поговорить
  • Вопрос задан
  • 232 просмотра
Решения вопроса 1
Compolomus
@Compolomus Куратор тега PHP
Комполом-быдлокодер
Сделал типо поиск по списку
Class Collection

class Collection
{
    public const ASC = 1;
    public const DESC = 0;

    private $generic;

    private $collection = [];

    public function __construct(string $class)
    {
        $this->generic = $class;
    }

    public function addOne(object $object): self
    {
        if (!($object instanceof $this->generic)) {
            throw new InvalidArgumentException(
                'Object mast be instanceof ' . $this->generic . ' class, ' . get_class($object) . ' given'
            );
        }
        $this->collection[] = $object;

        return $this;
    }

    public function addAll(array $objects): self
    {
        array_map([$this, 'addOne'], $objects);

        return $this;
    }

    public function count(): int
    {
        return count($this->collection);
    }

    public function immutable(): self
    {
        return clone $this;
    }

    public function getGeneric(): string
    {
        return $this->generic;
    }

    private function cmp(string $key, int $order): callable
    {
        return static function (object $a, object $b) use ($key, $order) {
            return $order ? $a->$key <=> $b->$key : $b->$key <=> $a->$key;
        };
    }

    public function where(string $query): self
    {
        $linq = new Linq($this);

        return (new self($this->getGeneric()))->addAll($linq->where($query)->get());
    }

    public function sort(string $key, int $order = Collection::ASC): self
    {
        uasort($this->collection, $this->cmp($key, $order));

        return $this;
    }

    public function delete(int $id): void
    {
        if (array_key_exists($id, $this->collection)) {
            unset($this->collection[$id]);
        } else {
            throw new InvalidArgumentException(
                'Key ' . $id . ' is not isset in collection'
            );
        }
    }

    public function limit(int $limit, int $offset = 0): self
    {
        $this->collection = array_slice($this->collection, $offset, $limit);

        return $this;
    }

    public function get(): array
    {
        return $this->collection;
    }
}


Class Linq

class Linq
{
    private $collection;

    private const CONDITIONS_TYPES = [
        '=',
        '!=',
        '>',
        '<',
        '<=',
        '>=',
    ];

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

    public function where(string $query): self
    {
        $pattern = '#(?P<field>.*)?(?P<condition>' . implode('|', self::CONDITIONS_TYPES) . ')(?P<value>.*)#is';

        preg_match($pattern, $query, $matches);

        $count = count($matches);

        if (!$count || $count < 4) {
            throw new InvalidArgumentException('Not matches ' . '<pre>' . print_r($matches, true) . '</pre>');
        }
        $args = array_map('trim', $matches);

        $array = [
            '=' => '===',
            '!=' => '!==',
        ];

        return $this->prepare(
            $args['field'],
            (in_array($args['condition'], $array, true) ? $array[$args['condition']] : $args['condition']),
            $args['value']
        );
    }

    private function condition($valFirst, string $condition, $valSecond): bool
    {
        switch ($condition) {
            case '=':
                return $valFirst === $valSecond;
            case '!=':
                return $valFirst !== $valSecond;
            case '>':
                return $valFirst > $valSecond;
            case '<':
                return $valFirst < $valSecond;
            case '>=':
                return $valFirst >= $valSecond;
            case '<=':
                return $valFirst <= $valSecond;
            default:
                throw new InvalidArgumentException('Condition not set');
        }
    }

    private function prepare(string $field, string $condition, $value): self
    {
        $new = new Collection($this->collection->getGeneric());

        foreach ($this->collection->get() as $val) {
            !$this->condition($val->$field, $condition, $value) ?: $new->addOne($val);
        }

        $this->collection = $new;

        return $this;
    }


    public function get(): array
    {
        return $this->collection->get();
    }
}


Class Changer

class Changer
{
    private $types = [];

    private $countTypes;

    private $nextType;

    public const NEXT = 1;
    public const RANDOM = 0;

    public static $count = 0;

    public function __construct(array $array, int $nextType = self::NEXT)
    {
        $this->types = $array;
        $this->countTypes = count($array);
        $this->nextType = $nextType;
    }

    public function getNext(): string
    {
        $type = $this->nextType ? $this->types[self::$count++] : $this->types[array_rand($this->types)];

        if (self::$count === $this->countTypes) {
            self::$count = 0;
        }

        return $type;
    }
}


Функция чтения каталога с файлами

function getFileList(string $dir): array
{
    $array = [];
    $fileSPLObjects = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator(realpath($dir)),
        RecursiveIteratorIterator::CHILD_FIRST
    );
    foreach ($fileSPLObjects as $fullFileName => $fileSPLObject) {
        if ($fileSPLObject->isFile()) {
            $array[] = $fullFileName;
        }
    }

    return $array;
}



// $array = getFileList('./clips');
$array = file('./files.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

$result = [];

foreach ($array as $key => $value) {
    $parts = explode(' ', $value);
    $params = explode('_', $parts[0]);
    $result[$key] = (object)[
        'pk' => $key,
        'author' => (int)$params[0],
        'type1' => $params[1],
        'type2' => $params[2],
        'name' => $value
    ];
}

$collection = new Collection('stdClass');
$collection->addAll($result);

$clipList = ['LZ', 'MD', 'BS'];
$special = ['AN', 'DB', 'KB'];

$playlist = [];

$genreList = new Changer($clipList);
$spList = new Changer($special);

for ($i = 0; $i < 640; $i++) {
    $stype = 'type1';
    if ($i) {
        $searchKey = $i % 7 === 0 ? $spList->getNext() : $genreList->getNext();
    } else {
        $searchKey = $genreList->getNext();
    }
    $linq = $collection->where($stype . ' = ' . $searchKey);
    if ($linq->count()) {
        $item = $linq->get()[0];
        $collection->delete($item->pk);
    } else {
        $item->name = 'Не найдено ' . $searchKey;
    }
    $playlist[] = $item->name;
}

echo '<pre>' . print_r($playlist, true) . '</pre>';
exit;
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы