LINUX.ORG.RU
ФорумTalks

Качалка COUB для вашего ПеКа

 coub, , , ,


2

1

Драсти опять я к вам со своим lua говнокодом. Товарищ @superuser скоромно сбросил в толксы свою качалку на баше. Не будем скромничать код по ссылке Coub закрывается (комментарий) Более того он ещё патчи исправления скидывает, похвала. Я взял смелость и переписал на lua немножко расширив список возможностей и теперь у нас конкурирующий бизънес! :D Вот вы хихи да хаха, а люди за скачивание даже платят, пруфов не дам :o) Скрипт качалка ниже совместим с версией от @superuser по части хранения coub`ов.

Как пользоваться.

  • В качестве входных параметров может выступать

    • ссылка на coub https://coub.com/view/2ppitj
    • идентификатор на coub 2dnd59
    • название уже скачанного coub Дело_говорит_Симпсоны
    • путь ~/COUB/Дело_говорит_Симпсоны
    • комбинация идентификатора, ссылки, пути и имени
    • 14ns7i,https://coub.com/view/2djrec,Дело_говорит_Симпсоны,2cljbw
    • список файлов должен идти в конце параметров и разделятся запятыми (впритык!)
    • список можно прочитать из файла cat mycoubs.txt | coub - или через ls из каталога
    • в файле разделять можно запятыми или переводом строки
  • Ключ -l задаёт количество повторений inf бесконечность

    • если задана последовательность coub то каждый из них проиграется столько раз сколько
      задано ключом -l если для последовательности coub’ов задан -l inf то каждый из ниж будет проигрываться вечно, при это наглядевшись на один нужно руками закрыть окно плеера откроется следующее видео и также будет по кругу идти, это удобно так как coub’ы часто смотрят по многу раз.
  • Ключ -d говорит о том что нужно просто скачать один или несколько coub’ов, проигрываться ничего не будет

Скрипт не ищет на coub по названиям типа Дело_говорит_Симпсоны этот запрос к программе для поиска локального файла.

Коубы указанные идентификатором или ссылкой всегда скачиваются, нет проверки был ли уже скачан коуб. Для уже скачанных используйте названия из ~/home/$USER/COUB .

Обработка параметров идёт через жъёпу! В начале ключи потом ссылки/id/имена или -. Значения разделены от ключей пробелом -l 3, урлы,id,имена запятыми без пробелов

Зависимости apt install lua wget лол


#! /bin/env lua
local coub = {} -- initial table for export like module
---------------------------------------------------------
coub.config =
{   -- coub save location, you can play from this dir
    storages = '/home/'..os.getenv('USER')..'/COUB';
    -- mp3, mp4 donwnload location, maybe userfull
    download = '/home/'..os.getenv('USER')..'/COUB/DATA';
}
---------------------------------------------------------
function coub.msg(text)
    print("\x1b[32m"..text.."\x1b[39m")
end

function coub.err(text)
    print("\x1b[31m"..text.."\x1b[39m")
end
---------------------------------------------------------
function coub.usage()
help = [[
Use: coub [-h] [-l Num] source

Options:
    -h  - Help and exit;
    -l  - Repeat audio Num times or inf for infinity;
    -d  - Download only
    -   - Read coub or coub list from stdin
    you can use full url or coub id
    source - url | id | file.mp4

Examples:
    # play single coub
    coub https://coub.com/view/38yafx
    # play single coub from storage
    coub ~/COUB/Don_t_be_egoistic
    # play single looped coub
    coub -l inf 38yafx
    # download single coub, no play this
    coub -d https://coub.com/view/38yafx
    # download multiply coubs with separated
    coub -d 38yafx,https://coub.com/view/38yafx
    coub -d 38yafx[newline]https://coub.com/view/38yafx
    cat mycoubs.txt | coub -d -
    # download and play multiply coubs (no looped)
    coub -d 38yafx,38yafx
    # play multiply coubs from file id list
    cat mycoubs | coub -
    ]]
    print(help)
end
-----------------------------------------------------------
local function filter_get_between(body,a,b)
    local s , e = 1 , 1;
    local out = ""
        s,e = body:find(a,1,true);
        if s == nil or e == nil then return end
        local ss,ee = body:find(b,s,true);
        if ss == nil or ee == nil then return end
        out = out .. body:sub(e+1,ss-1);
        body = body:sub(ee,#body)

    return out;
end
-----------------------------------------------------------
function coub:run()
    -- stupid handle va_args
    for k,v in ipairs(arg) do
        if self.xoop then self.loop = v; self.xoop = nil; end
        if v == '-h' then self.usage();     end
        if v == '-l' then self.xoop = 1;    end
        if v == '-d' then self.dl_only = 1; end
        self.resource = v
    end
    if not self.loop then
        self.loop = 0;
    elseif self.loop == 'inf' then
        -- do nothing
    else
        self.loop = tonumber(self.loop);
        if self.loop > 0 then
           self.loop = self.loop - 1;
        end
    end

    -- decrement loop value becouse loop value =  N+1
    -- mpv --loop=0 is once play and --loop=1 twoo play


    if not self.resource then
        coub.err("Bad coub: no have input");
        coub.usage()
    end

    -- read input from stdin
    local cnt = 1;
    if self.resource == '-' then
       self.resource = io.read("*all");
    end
    -- check is resource contains data
    -- min 2 symbol coub id (yea?)
    if #self.resource < 2 then
        coub.err('Bad data: Input source is empty');
        return; 
    end
    -- tokenization play lists, and concat to URL
    -- тут ещё нужно проверить может нужные коубы уже скачаны
    self.playlist = {}
    for resource in string.gmatch(self.resource, '([^,\n]+)') do
        if resource:find('https',1,true) then
            self.playlist[cnt] = resource;
        elseif resource:find('/',1,true) or resource:find('.',1,true) then
            self.playlist[cnt] = resource;
        else
            self.playlist[cnt] = 'https://coub.com/view/'..resource;
        end
        cnt = cnt + 1;
    end
    -- always make needed directory
    assert(os.execute('mkdir -p '..self.config.storages),"Storage no writable");
    assert(os.execute('mkdir -p '..self.config.download),"Storage no writable");
    -- download coubs & play coubs --------------------------------------------
    for i,v in ipairs(self.playlist) do

        local exec = io.popen('wget -q -O- '..v);
        local html = exec:read('*all'); exec:close();
        -- wget 
        if  html:match('%a+') then
            local json = filter_get_between(html,"<script id='coubPageCoubJson' type='text/json'>",'</script>');
            local url_video = filter_get_between(json,'"video":{"higher":{"url":',',');
            -- some video no have higher resulution
            -- try get lowless
            if not url_video then
                 url_video = filter_get_between(json,'"video":{"high":{"url":',',');
            end
            local url_audio = filter_get_between(json,'"audio":{"high":{"url":',',');
            local coubtitle = filter_get_between(json,'"title":"','",');
            coubtitle = coubtitle:gsub('[%p+%s+]','_');
            local coubid    = v:gsub('https://coub.com/view/','');
            coub.msg('Download:['..i..'] '..v..' | '..coubtitle)
            -- check file format befor try handle data
            if url_video and url_video:find('.mp4',1,true) and url_audio and url_audio:find('.mp3',1,true) then
               local file_to_save = self.config.download..'/'..coubid;
               os.execute('wget -q -Y off -c -O '..file_to_save..'.mp4 '..url_video);
               os.execute('wget -q -Y off -c -O '..file_to_save..'.mp3 '..url_audio);
               os.execute('ln -s '..file_to_save..'.mp4 '..self.config.storages..'/'..coubtitle..' 2>/dev/null');

               -- do not play if need just download video
               if not self.dl_only then
                   -- play audio in background with infinity loop
                   os.execute('( mpv --loop=inf '..file_to_save..'.mp3 ) 1> /dev/null  & '..
                              -- play video, after video ends we kill previos mpv 
                              -- stdout to /dev/null becouse kill broke terminal stdin
                              -- maybe becouse mpv use '\r' for output info about playing
                              ' mpv --loop='..self.loop..' '..file_to_save..'.mp4 1> /dev/null ; kill -INT $! ');
               end
            else
                coub.err('Bad coub:['..i..'] file formats no mp3 and mp4 '..v);
            end
        else
            if v:find('~',1,true) then
                v = v:gsub('~',os.getenv('HOME'))
            else 
                v = self.config.storages..'/'..v:gsub('https://coub.com/view/','');
            end
            local justplay = io.open(v,'r');
            if justplay then
               justplay:close();
                  if not self.dl_only then 
                    coub.msg('PlayFile:['..i..'] '..v)
                    local link = io.popen(' readlink -e '..v);
                    local file = link:read('*all'); link:close();
                    os.execute('( mpv --loop=inf '..file:gsub('mp4','mp3')..' ) 1>/dev/null  & '..
                          ' mpv --loop='..self.loop..' '..file..' 1>/dev/null ; kill -INT $! ');
                  else
                    coub.msg('Ignore..:['..i..'] coub '..v..' is downloaded')
                  end
            else 
                coub.err('Bad coub:['..i..'] coub not found '..v);
                coub.err('Bad coub:['..i..'] coub not found https://coub.com/view/'..
                        v:gsub(os.getenv('HOME')..self.config.storages,''));
            end
        end
    end
end

coub:run()

- Баги косяки, тупак, есть?
- Да. 
- Исправлять будешь? 
- Нет. 
- А почему? 
- Ну модет потом... 
- А нахера всё это? 
- А тебе не пофиг?
- Пофиг
- Ну и всё
- Ну и ладно
- Ненужно!
- Согласен
- А зачем тогда?
- Потому что.
- Потому что что?
- Потому что понедельник!
- Ой всё.
- Вот и я о том.

Подборочка

coub yaik,s08ov,8ek0p,7aenz,bslpw,5g1j9,wm3bk,14zilh,7l1rdrfc,2b5izx,2aatx2,29jdfr,29k4yq
coub 29n55n,29j3j1,10a9jk,297dvo,280v0q,29adcz,29aon6,29gzt6,1qrxao,334db,15egdcy8,lvd3c

Фъъсьооо!

★★★★★

Последнее исправление: LINUX-ORG-RU (всего исправлений: 4)
Ответ на: комментарий от LINUX-ORG-RU

Я думал ты вообще никаким боком к играм

Джемы – это весело, хоть меня и блевать тянет от всяких юнити. А ещё я в PS2 последние пару лет рублюсь, всё хочу PS2SDK ткнуть палкой (ну или хотя бы Enceladus).

CYB3R ★★★★★
()
Ответ на: комментарий от CYB3R

У mpv заявленная фича, расширение функционала скриптами lua.

mpv имеет большое количество разнообразных скриптов, расширяющих функционал плеера. С этой целью он имеет внутренние привязки как для Lua, так и для JavaScript.
https://wiki.archlinux.org/title/Mpv#Scripts

Сам частенько ‘дергаю’ готовые отсюда, https://github.com/mpv-player/mpv/wiki/User-Scripts#lua-scripts.

krasnh ★★★★
()
Последнее исправление: krasnh (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Не, на это я забил ещё в школе. Тогда реально задрачивал геометрю на плоскости, высчитывал коллизии, писал физический движок, потом освоил Box2D. Сейчас я понял, что чтобы реально сделать игру нужен дедлайн. Дедлайн через 48 часов – это идеально для простой игры без особого смысла.

CYB3R ★★★★★
()
Ответ на: комментарий от krasnh

Сейчас из интереса залогинился на Ubuntu:

$ mpv
mpv 0.27.2 (C) 2000-2017 mpv/MPlayer/mplayer2 projects
...

$ lua

Command 'lua' not found, but can be installed with:

sudo apt install lua5.1
sudo apt install lua5.2
sudo apt install lua50

CYB3R ★★★★★
()
1 апреля 2023 г.

А есть скачивалка для ютуба на православном Lua? Знаю только на питоне поделия

Простите за некрофилию

friedrich
()
Последнее исправление: friedrich (всего исправлений: 1)
Ответ на: комментарий от dataman

Спасибо, буду дома - проверю работоспособность. А вообще допилить до рабочего состояния тоже классно было бы

friedrich
()
8 июня 2023 г.

Вопрос к @LINUX-ORG-RU, как единственному ) известному мне знатоку lua. Можно ли идею данного скрипта mpvEPG, реализовать при просмотре любых IPTV плейлистов через mpv?

Все же IPTV через mpv, это легко, но вот чтобы и программа (EPG) была…

https://ibb.co/N6GKYdx.

krasnh ★★★★
()
Ответ на: комментарий от krasnh

знатоку lua

Да нее, я нубяра, просто палочкой тыкаю

Можно ли идею данного скрипта

Ща, кашку доем, чай попью, икну и погляжу.

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от krasnh

любых IPTV плейлистов

А как они вообще выглядят? И они бывают разными? Есть примеры того какие плейлисты ты хочешь смотреть? Можно ссылки, файлы? А то мало ли какие нюансы.

Потыкаю, отпишу об успехах. По идее можно чёб нет то.

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Как одна из возможностей получить ссылку на IPTV плейлист - ПазлТВ, о котором писал здесь Ace Stream (комментарий).

Качаем архив:

  • Распаковать
  • Перейти в папку ptv3
  • python2 server.py

Получаем ссылку на плейлист http://127.0.0.1:8185/playlist и epg http://127.0.0.1:8185/epg/xmltv. Их и подставлять.

Пример, mpv http://127.0.0.1:8185/playlist.

Скрин, https://ibb.co/gMtnYqQ.

UPD. По умолчанию, вместо 127.0.0.1 ПазлТВ использует IP.

krasnh ★★★★
()
Последнее исправление: krasnh (всего исправлений: 2)

Я взял смелость и переписал на lua

Смелость нужна чтобы вынести насмешки по поводу выбора языка?

ox55ff ★★★★★
()
Ответ на: комментарий от Vsevolod-linuxoid

Если прокоуб то наверное умеет, к слову уже не нужно в коуб появилась кнопочка скачать, если нажать можно получать прямые ссылки

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от ox55ff

Давай! Насмехайся! Луа это это ушибленная на логолову гениальная эквилибростка, дочка Си бати. Си батя тебе навтыкает по самые регистры, а дочка придёт к тебе в ночи в виде трёх короутин работающийх поверх патча Coco

И будут наблюдать как ты пытаешься прибить процессы через PIDOFFF :D

Насмехайся, дувай, дувай!

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от dataman

Сишный выделенный стек для сопрограммы vs состояние виртуальной машины. На деле я не вникал, суть в том что быстрее и снимаются некоторые ограничения описанные тут https://coco.luajit.org/

Но и появляются приколы LuaJit coroutines/сопрограммы - вопросик по адекватности происходящего Я по этому пооду и пошутил, в lua ванильной послал SIGINT всё легло, в коке один упал, остальные дальше едут крича хаха лохъъъ нипапал нипапал! :D А luajit такая, а я чё у тя Ъкорутины, все вопросы к АБИЭМ ПИКА.

Но я не вникал longjump там или чего вообще и как.

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)

Узнал автора по красным вставкам кода не к месту.

chenbr0
()
Ответ на: комментарий от krasnh

Так, ptv3 на пихтоне, плюс на втором которого даже в репах нету, чинить не буду. А посему вопрос.

Скрин, https://ibb.co/gMtnYqQ.

Тут ты просматриваешь IPTV через m3u плейлист? Правильно, не какой то там специальный который идёт в паре с EPG XML.

На мой вгляд, самым правильным будет выкинуть вообще всё. Затем Найти список ссылок

  • Актуальных m3u плейтистов
  • Актуальных EPG программ телепередач

И там и там как минимум должны быть нормальные идентификаторы каналов для просто сопоставления.

Затем при первом включении mpv раз в сутки дрёгаются ссылки, каналы сопоставляются с EPG и генерируется нативный lua конфиг на текущие сутки из списка каналов (ссылок на поток) и соответствующих им списка передач на каждый из каналов.

По сути m3u плейтисты статичны и не требуют обновлений, висит себе поток и висит. А вот актуальные EPG уже меняются.

И потом эти данные уже поверх mpv ass draw нарисовать задницу… в смысле морду всего этого.

Короче всё надо делать с нуля. Если интерес не пропадёт по вечерам буду тыкать, но сначала надо покурить mpv API и надыбать надёжные источники как m3u так и EPG

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Тут ты просматриваешь IPTV через m3u плейлист?

Этот скрин отображает команду mpv http://127.0.0.1:8185/playlist. Плюс там установлено управление плейлистом с playlistmanager.lua.

На мой вгзляд, самым правильным будет выкинуть вообще всё. Затем Найти список ссылок

Использовал «ссылку на плейлист 127.0.0.1:8185/playlist и epg 127.0.0.1:8185/epg/xmltv» в yuki-iptv (форк Astroncia IPTV).
Мне там понравилось, что листаешь плейлист с каналами, и сразу видишь что показывают и сколько процентов осталось.
Скрин https://ibb.co/b2cF3Cf.

Но mpv более легкий плеер, конечно. И у него есть своя ниша.

krasnh ★★★★
()
Последнее исправление: krasnh (всего исправлений: 1)
Ответ на: комментарий от krasnh

Понятно. Ну судя по срину всё норм и из коробки. Смысла особого пилить тоже самое нет, ладно, если чво будет сделано отпишу/поделюсь. А пока, пока используй yuki-iptv как по мне отлично выглядит.

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Понятно. Ну судя по срину всё норм и из коробки.

Чтобы не было недопонимания, ) первый скрин (mpv) - там чисто http-плейлист с каналами. Никакого EPG (программы) там нет.

UPD. И mpvEPG.lua я тоже не использую, у него узкая ниша - показывать программу, а это как раз и не работает.
А вот чтобы через mpv смотреть IPTV, ничего дополнительно не требуется, у него все есть из коробки.

krasnh ★★★★
()
Последнее исправление: krasnh (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Короче всё надо делать с нуля.

Я думал, там всего лишь достаточно оживить с учетом реалий 2023 года. 😀 Ну там парсер xmltv какой-нибудь современный в замену неработающему SLAXML. Плюс код обновить, все же коммиты 3 года назад…

krasnh ★★★★
()
9 апреля 2024 г.

Оставлял свои комменты, как воспроизводить coub через mpv на лету. А если скачать с yt-dlp аудио и видео, то их можно было подставить в первый код, для воспроизведения локальных файлов.


Но вот наткнулся на код скачивания/слияния, где на выходе полноценный файл coub.
Даю обе команды. У меня ffmpeg 5, сработала первая. Ссылку на видео взял из подборки в шапке темы.


yt-dlp --ppa "Merger+ffmpeg_i1:-stream_loop -1" --ppa "Merger+ffmpeg_o1:-shortest" https://coub.com/view/280v0q

####ffmpeg 6
yt-dlp --ppa "Merger+ffmpeg_i1:-stream_loop -1" --ppa "Merger+ffmpeg_o1:-shortest -shortest_buf_duration 0" https://coub.com/view/280v0q
$ yt-dlp --ppa "Merger+ffmpeg_i1:-stream_loop -1" --ppa "Merger+ffmpeg_o1:-shortest" https://coub.com/view/280v0q

[Coub] Extracting URL: https://coub.com/view/280v0q
[Coub] 280v0q: Downloading JSON metadata
[info] 280v0q: Downloading 1 format(s): html5-video-high+html5-audio-high
[download] Destination: Memories from the Future [280v0q].fhtml5-video-high.mp4
[download] 100% of    3.44MiB in 00:00:01 at 1.85MiB/s
[download] Destination: Memories from the Future [280v0q].fhtml5-audio-high.mp3
[download] 100% of    3.89MiB in 00:00:01 at 2.04MiB/s
[Merger] Merging formats into "Memories from the Future [280v0q].mp4"
Deleting original file Memories from the Future [280v0q].fhtml5-video-high.mp4 (pass -k to keep)
Deleting original file Memories from the Future [280v0q].fhtml5-audio-high.mp3 (pass -k to keep)


$ ls -lh
-rw-r--r-- 1 live live 67M дек 18  2022 'Memories from the Future [280v0q].mp4'

krasnh ★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)