Думаю, все помнят telnet версию SW:New Hope. В связи с блокировкой PornHub'а, возникла идея сделать что-то подобное с их видео. Вооружимся питоном и попробуем реализовать задумку.


Тот самый StarWars.

1. Добыча контента


У порнхаба есть довольно внятное апи, поэтому воспользуемся им. Описание находится здесь (к сожалению, придется зарегистрироваться). С его помощью можно вытянуть ссылки на страницы с видео, но далее нам все же придется копаться в html. К счастью, нужная ссылка легко выдирается с помощью регулярки:

def getVideoUrl(pageUrl):
    response = urllib2.urlopen(pageUrl)
    content = response.read()

    videoRegex = re.compile(r'player_quality_\d+p\s+=\s+\'(?P<url>.+?\';)')
    m = videoRegex.search(content)
    url = m.group('url')
    return url

Что еще стоит отметить на данном этапе: pornhub периодически возвращает 403 при попытке скачать видео, решается эта проблема сменой User-Agent.

2. Конвертация


Теперь нам нужно сконвертировать видео в ASCII графику. Для этого воспользуемся OpenCV. Алгоритм крайне простой:

  • RGB -> Grayscale
  • Downscale до нужного разрешения
  • Преобразование пикселей в символ

Так как мы собираемся выводить результат в telnet, возьмем за основу разрешение 80х24:

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
res = cv2.resize(gray, (80, 24))

Думаю, следует пояснить зачем мы конвертируем в grayscale: нас интересует только информация об освещенности, ее можно получить двумя способами — сконвертировать в YUV и вытащить Y канал или сконвертировать в grayscale.

Далее нам просто нужно проитерироваться по пикселям и сконвертировать полученные значения в символы:

def lumToChar(l):
    result = '@'
    if l >= 230.0:
        result = ' '
    elif l >= 200.0:
        result = '.'
    elif l >= 180.0:
        result = '*'
    elif l >= 160.0:
        result = ':'
    elif l >= 130.0:
        result = 'o'
    elif l >= 100.0:
        result = '&'
    elif l >= 70.0:
        result = '8'
    elif l >= 50.0:
        result = '#'
    return result

3. Вывод в telnet


Все, что нам осталось сделать — поднять tcp сервер и при подключении стримить туда наше видео. Однако, тут есть загвоздка: каждый кадр нужно очищать буффер. Для этого просто посылаем клиенту escape-последовательность:

escapeSeq = '\033[2J'

NSFW
image
Угадайте, что это.

4. Заключение


Q: Зачем?
A: Было свободное время.
Q: Где можно пощупать результаты?
A: telnet 185.146.170.134 9002
Поделиться с друзьями
-->

Комментарии (35)


  1. pewpew
    16.09.2016 15:53
    +21

    Это ж надо так оголодать…
    Однако месье толк знает


  1. atomlib
    16.09.2016 16:02
    +4

    Всё уже есть. Роскомнадзору только не показывайте.

    www.asciipr0n.com


    1. PapaBubaDiop
      16.09.2016 16:39

      Надо это скормить реккурентной нейросети и посмотреть, что она породит.


      1. skylevels
        16.09.2016 22:20

        Просто оставлю это здесь http://antio.ru/index.php?showtopic=36369&page=1


  1. maxDanylenko
    16.09.2016 16:26
    -2

    Если вы не интересуетесь политикой, это не значит, что она на вас не влияет и на вашу жизнь. Я думаю, это хороший урок.


    1. maxDanylenko
      16.09.2016 17:06
      -1

      Вместо решения норм проблем, человек решает проблемы, которые создалы государством, вот по этому и в жопе


  1. susnake
    16.09.2016 16:35

    Хмм..Win10 как-то странно работает
    image


    1. Filippok
      16.09.2016 16:49

      На винде есть проблемы, да. Есть подозрения, что из-за CRLF. Вечером попробую разобраться.


      1. Radic
        16.09.2016 19:59
        +1

        На macOS тоже проблемы, мерцание.


      1. Biga
        16.09.2016 22:41
        +1

        Эту программу можно не только смотреть, но и потрахаться с её отладкой.


    1. jok40
      16.09.2016 16:52

      Слишком примитивный клиент. Попробуйте другим — в котором можно что-нибудь поднастроить. Например, SecureCRT показывает. У него, правда, не очень качественный скроллинг, из-за которого картинка мерцает и дёргается.


      1. xProtosx
        16.09.2016 17:15

        Странно, у меня через SecureCRT только мерцание, м.б. топик стартер прекратил вещание?


        1. Filippok
          16.09.2016 17:17

          Нет, сервер работает. На момент написания этого поста к нему поключены 95 человек =)


          $ ps -ax | grep play | grep -v grep | grep -v SCREEN | wc -l
          96

          Один родительский процесс, и 95 дочерних.


          1. asm0dey
            16.09.2016 22:41

            ps -ax | grep '[p]lay' | grep -v SCREEN | wc -l


            на один сабшелл меньше.


        1. jok40
          16.09.2016 17:34

          Сейчас проверил — показывает. Нужно только в настройках включить опцию «New line mode» (Terminal->Emulation->Modes).


  1. grims
    16.09.2016 16:39

    Каким размером должно быть окно, стандартное не кажет.


  1. inoyakaigor
    16.09.2016 16:50

    Сервер лёг под хабраэффектом?


  1. KorP
    16.09.2016 16:52

    А нельзя как VLC в консоли?
    image
    image


    1. Filippok
      16.09.2016 16:58

      Можно. Но писалось оно как proof-of-concept, поэтому с цветами я заморачиваться не стал.


  1. Boomburum
    16.09.2016 16:59
    +1

    ru-домена порнхаба мало? )


  1. ValdikSS
    16.09.2016 17:19

    У видео изначально цветовой формат YUV 4:2:0, можно сразу вытаскивать Y, а не преобразовывать YUV в RGB, а RGB в Greyscale.


    1. Filippok
      16.09.2016 17:37

      Возьму на заметку. Спасибо.


  1. OdaN
    16.09.2016 17:38

    а чем не устроили эти двое?
    https://en.wikipedia.org/wiki/AAlib
    https://en.wikipedia.org/wiki/Libcaca


    1. Filippok
      16.09.2016 17:45
      +2

      Не спортивно =)


  1. basili4
    16.09.2016 17:49
    +2

    Странно все это у меня как работал как и работает. Наверное админ моего прорва, купился на премиум аккаунт.


  1. kalobyte
    16.09.2016 19:22

    как все просто оказалось, а я думал будет куда сложнее

    самое главное — значение яркостей и соответствующие им символы
    а вот откуда их взять? и как вообще додумались до такого?


    1. MacIn
      16.09.2016 20:47

      Чем больше площадь символа, тем больше пикселей светится=тем ярче. Вроде, очевидно, нет?


      1. kalobyte
        16.09.2016 21:47

        мне не очевидно
        я думал символы должны подходить по форме как-то

        вон там ниже камент как раз про форму символов


        1. MacIn
          16.09.2016 22:22

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

          У вас есть функция, которая связывает яркость пикселя с символом. Не блок пикселей (что могло бы определить форму), а яркость.


  1. darkdaskin
    16.09.2016 20:00
    +1

    Гораздо интереснее результат бы выглядел, если бы использовалась форма символов, а не только плотность. Можно попробовать воспользоваться поиском границ из того же OpenCV, затем порезать картинку на клетки и преобразовать линии различной формы в наиболее похожие символы.


  1. zcasper
    16.09.2016 20:09
    +1

    о боги, символы что попало делают ))


  1. mikevmk
    16.09.2016 21:19
    +1

    Что-то прыгает изображение


  1. TimsTims
    16.09.2016 21:35
    +2

    Вспомнил фильм «Матрица», там оператор тоже глядел на похожую матрицу и наблюдал за девушками)


  1. V0ldemar
    17.09.2016 09:40

    telnet 185.146.170.134 9002


    А как выбирался номер порта? Странное совпадение, 9002 это вроде ASN RETN.


  1. Alexeyslav
    13.01.2017 15:39

    Как-то вот так схема должна выглядеть.


    Под рукой правда редактора не было, пришлось обойтись Спринтом.