Тот самый 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'
Угадайте, что это.
4. Заключение
Q: Зачем?
A: Было свободное время.
Q: Где можно пощупать результаты?
A: telnet 185.146.170.134 9002
Комментарии (35)
atomlib
16.09.2016 16:02+4Всё уже есть. Роскомнадзору только не показывайте.
www.asciipr0n.com
maxDanylenko
16.09.2016 16:26-2Если вы не интересуетесь политикой, это не значит, что она на вас не влияет и на вашу жизнь. Я думаю, это хороший урок.
maxDanylenko
16.09.2016 17:06-1Вместо решения норм проблем, человек решает проблемы, которые создалы государством, вот по этому и в жопе
susnake
16.09.2016 16:35Хмм..Win10 как-то странно работает
jok40
16.09.2016 16:52Слишком примитивный клиент. Попробуйте другим — в котором можно что-нибудь поднастроить. Например, SecureCRT показывает. У него, правда, не очень качественный скроллинг, из-за которого картинка мерцает и дёргается.
xProtosx
16.09.2016 17:15Странно, у меня через SecureCRT только мерцание, м.б. топик стартер прекратил вещание?
Filippok
16.09.2016 17:17Нет, сервер работает. На момент написания этого поста к нему поключены 95 человек =)
$ ps -ax | grep play | grep -v grep | grep -v SCREEN | wc -l 96
Один родительский процесс, и 95 дочерних.
jok40
16.09.2016 17:34Сейчас проверил — показывает. Нужно только в настройках включить опцию «New line mode» (Terminal->Emulation->Modes).
basili4
16.09.2016 17:49+2Странно все это у меня как работал как и работает. Наверное админ моего прорва, купился на премиум аккаунт.
kalobyte
16.09.2016 19:22как все просто оказалось, а я думал будет куда сложнее
самое главное — значение яркостей и соответствующие им символы
а вот откуда их взять? и как вообще додумались до такого?MacIn
16.09.2016 20:47Чем больше площадь символа, тем больше пикселей светится=тем ярче. Вроде, очевидно, нет?
kalobyte
16.09.2016 21:47мне не очевидно
я думал символы должны подходить по форме как-то
вон там ниже камент как раз про форму символовMacIn
16.09.2016 22:22я думал символы должны подходить по форме как-то
У вас есть функция, которая связывает яркость пикселя с символом. Не блок пикселей (что могло бы определить форму), а яркость.
darkdaskin
16.09.2016 20:00+1Гораздо интереснее результат бы выглядел, если бы использовалась форма символов, а не только плотность. Можно попробовать воспользоваться поиском границ из того же OpenCV, затем порезать картинку на клетки и преобразовать линии различной формы в наиболее похожие символы.
TimsTims
16.09.2016 21:35+2Вспомнил фильм «Матрица», там оператор тоже глядел на похожую матрицу и наблюдал за девушками)
V0ldemar
17.09.2016 09:40telnet 185.146.170.134 9002
А как выбирался номер порта? Странное совпадение, 9002 это вроде ASN RETN.
Alexeyslav
13.01.2017 15:39Как-то вот так схема должна выглядеть.
Под рукой правда редактора не было, пришлось обойтись Спринтом.
pewpew
Это ж надо так оголодать…
Однако месье толк знает