Аналитика

Яндекс Диск. «Защита» от копирования

Данная статья создана исключительно в информационно-ознакомительных целях. Автор не призывает читателей повторять описанный опыт.

У Яндекса, как и у многих других, есть файловое хранилище под названием Яндекс Диск. Помимо прочего, данный сервис позволяет хранить и воспроизводить видео. Более того, при наличии подписки Яндекс 360 появляется возможность тонкой настройки безопасности при распространении публичных ссылок на файлы. В число таких настроек входит:

  • Пароль, который потребуется для просмотра файла:
  • Невозможность скачивания файла и сохранения его к себе на Диск:
  • Срок действия публичной ссылки на файл.

Среди вышеперечисленного меня заинтересовала невозможность скачать файлы по предоставленной публичной ссылке. Неплохая заявка на «защиту» от копирования материалов, которые нужно кому-либо показать, но не «отдавать». Проверим как это выглядит…

Подготовка

Я купил подписку Яндекс 360 на месяц (199 руб/мес. без всяких скидок на 07.01.2024) и сразу отключил ее. Если этого не сделать, то будет включено автоматическое продление, которое, очевидно, мне без надобности.

Далее нужен какой-нибудь сайт, который даст возможность скачать небольшое видео без лицензионных ограничений. как раз для таких целей есть данный сайт, где я скачал «Проезжающий мимо парка поток автотранспорта» длительностью 15 секунд и размером 12 Мб — то, что надо. Теперь необходимо загрузить видео на Диск. Подробно на этой части останавливаться не буду.

Для последующего анализа потребуется сделать данное видео публичным и запретить его скачивание. В контекстном меню (ПКМ1 на файле) выбираю «Поделиться», включаю запрет на скачивание и копирую ссылку.

Чтобы не выходить из своей учетной записи открываю ссылку в новом инкогнито окне браузера и вижу готовый к воспроизведению проигрыватель.
Ниже для сравнения показываю как выглядит страница с проигрывателем без включенного запрета на скачивание и с ним.

Анализ получения данных

Поглядим откуда берется видеопоток. Открываю инструменты разработчика в браузере (F12), а точнее вкладку для анализа сетевого трафика (Network). Запускаю воспроизведение и смотрю видео до конца (оно же короткое) чтобы записались все сетевые запросы. После этого останавливаю запись сетевых запросов чтобы не появлялось лишнего мусора.

В зависимости от длины и качества видео будет различное количество итоговых запросов:

Среди всего этого разнообразия нам необходимы лишь те запросы, которые показывают загрузку чего-либо. Для этого имеется возможность применить фильтр «Fetch/XHR» (одна из кнопок над списком запросом). Отфильтрованный перечень запросов выглядит уже лучше. Более того, сразу можно увидеть те запросы, ответ в которых содержал максимальное количество информации (по размеру):

Забегая немного вперед, сразу скажу, что если перейти в браузере по адресу любого из указанных выше запросов, то будет предложено сохранить некий файл с расширением *.ts. При сохранении станет ясно, что это видеофайл, а если точнее, то фрагмент видео, которое воспроизводилось. Очевидно, что другой запрос также является фрагментом воспроизведенного видео. Единственный недостаток сохраненного файла (не считая того, что видео неполное) – отвратительное качество. Во время просмотра видео в проигрывателе было установлено качество 240p. Устанавливаю 720p и повторяю процедуру записи сетевых пакетов.

При сравнении между собой полных адресов запросов первой (240p) и второй (720p) попытки записи сетевых пакетов (сравнивать можно тут) получается следующий паттерн:

Если выкинуть все параметры запроса после предполагаемого идентификатора видео и перейти в браузере по оставшемуся адресу, подставив максимальный порядковый номер видео фрагмента, то браузер предлагает сохранить последний фрагмент видео в указанном качестве!

Уже на данном этапе можно заявить, что при должном уровне терпения удастся скачать полное видео, разделенное на несколько файлов/фрагментов.

Автоматизация процесса скачивания

Процесс скачивания всего видео заключается в последовательном выполнении запросов по загрузке фрагментов видео по их порядковому номеру. С данной задачей прекрасно справится утилита curl. При помощи следующей команды можно скачать в текущую директорию один фрагмент (под порядковым номером 3) видео в качестве 720p, сохранив его с именем output3.ts:

:: Некоторые части ссылки сокращены для удобства восприятия
curl -o output3.ts "https://streaming.disk.yandex.net/hls/.../720p/3.ts?from=disk&vsid=..."

Для автоматизации процесса загрузки всех фрагментов видео я набросал скрипт для командной оболочки Windows:

@ECHO OFF
SETLOCAL

:: Данная переменная хранит стартовый адрес загрузки фрагмента видео 
:: вплоть до порядкового номера фрагмента, ВКЛЮЧАЯ качество видео
SET PRE_URL="https://streaming.disk.yandex.net/hls/.../720p/"

:: Данная переменная хранит часть адреса загрузки фрагмента видео, 
:: которая идет сразу после порядкового номера фрагмента 
:: и заканчивается идентификатором видео (до знака &, не включая его)
SET POST_URL=".ts?from=disk&vsid=..."

:: Переменная наименования директории, в которую будут сохранены фрагменты
SET DOWNLOAD_DIR=output

:: Создание директории для сохранения фрагментов
MKDIR %DOWNLOAD_DIR%

:: Запуск цикла скачивания каждого фрагмента по порядку, 
:: начиная с 1 и заканчивая 3 с шагом равным 1.

:: Каждый фрагмент будет сохранен в указанную выше директорию 
:: с именем output<порядковый номер>.ts

:: Синтаксис %PRE_URL:"=% указывает на переменную PRE_URL, 
:: из которой удалены символы кавычек
FOR /L %%A IN (1,1,3) DO (
  curl -o %DOWNLOAD_DIR%\output%%A.ts "%PRE_URL:"=%%%A%POST_URL:"=%"
)

После запуска скрипта получаем фрагментированное видео, для которого установлен запрет на скачивание!

Объединение фрагментов

Для работы с видео из консоли есть прекрасная утилита ffmpeg, которая позволяет одной простой командой объединить несколько фрагментов видео в единый файл.

Скачать ffmpeg для своей операционной системы можно отсюда. Для объединения фрагментов ffmpeg предлагает 2 метода:

  1. The concat «demuxer»

Для данного метода потребуется файл, в котором будут перечислены имена файлов всех фрагментов для объединения в следующем формате:

# Это комментарий
file '/путь/до/output1.ts' # Для Windows: 'С:\путь\до\output1.ts'
file '/путь/до/output2.ts'
file '/путь/до/output3.ts'

После создания файла достаточно запустить ffmpeg следующей командой:

:: -f concat - метод объединения demuxer
:: -safe 0 - проверка пути до указываемого файла
:: -i files.txt - абсолютный или относительный путь до созданного ранее файла
:: -c copy - создание итогового файла безе перекодирования видео/аудио потоков
:: output_full.mp4 - имя итогового файла
ffmpeg -f concat -safe 0 -i files.txt -c copy output_full.mp4

При указании относительного пути до files.txt параметр -safe 0 можно не указывать.

  1. The concat «protocol»

При использовании этого метода никаких файлов не нужно, достаточно использовать специальный синтаксис при запуске ffmpeg:

:: Возможно, потребуется экранировать разделитель между файлами, 
:: т.к. он является специальным для некоторых оболочек
ffmpeg -i "concat:/путь/до/output1.ts|/путь/до/output2.ts|/путь/до/output3.ts" -c copy output_full.mp4

Внимание! При использовании любого из методов важно корректно указывать порядок входящих файлов, т.к. объединение производится именно в указанном порядке.

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

Для себя я выбрал первый метод. Осталось только сгенерировать корректный файл. Набросал простенькую программу на Java:

import java.nio.charset.*;
import java.nio.file.*;
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;

public class VideoMerger {

    // Паттерн регулярного выражения, который предполагает имя файла 
    // с порядковым номером непосредственно перед расширением
    private static final Pattern INPUT_FILE_PATTERN = Pattern.compile("^.*?(\\d+)\\.[A-Za-z-_]+$");

    public static void main(String[] args) throws Exception {
        // Получение потока файлов из директории, которая передается первым аргументом к программе
        try (Stream<Path> filesStream = Files.walk(Paths.get(args[0]), 1)) {
            List<String> fileList = filesStream.filter(path -> !path.toFile().isDirectory()) // оставляем только файлы
                    // Сортировка файлов
                    .sorted((o1, o2) -> {
                        // Применение указанного выше паттерна к каждой паре файлов
                        Matcher m1 = INPUT_FILE_PATTERN.matcher(o1.getFileName().toString());
                        Matcher m2 = INPUT_FILE_PATTERN.matcher(o2.getFileName().toString());
                        m1.find();
                        m2.find();
                        // Выделение целочисленного порядкового номера из каждого файла в парах
                        int i1 = Integer.parseInt(m1.group(1));
                        int i2 = Integer.parseInt(m2.group(1));
                        // Сортировка файлов по возрастанию порядкового номера
                        return i1 - i2;
                    })
                    // Приведение каждого файла к требуемому формату для дескриптора
                    .map(path -> "file '" + path.toAbsolutePath().toString() + "'")
                    // Сборка к коллекцию
                    .collect(Collectors.toList());
            // Запись файла-дескриптора для ffmpeg
            Files.write(Paths.get(args[1], "files.txt"), fileList, StandardCharsets.UTF_8);
        }
    }
}

Данную программу необходимо сохранить в файле VideoMerger.java. После этого потребуется открыть консоль в директории, где был сохранен данный файл, скомпилировать исходный код в исполняемый и запустить программу:

Установка и настройка JDK для компиляции и запуска Java программ выходит за рамки данной статьи.

:: Компилируем исходный код
javac VideoMerger.java
:: Запускаем программу
java VideoMerger "/путь/до/загруженных/фрагментов" "/путь/для/сохранения/дескриптора/ffmpeg"

На выходе будет готовый файл-дескриптор для работы ffmpeg:

Осталось запустить ffmpeg:

ffmpeg.exe -f concat -safe 0 -i D:\...\...\output\files.txt -c copy D:\...\...\output\output_full.mp4

По итогу получаем полное видео в указанном качестве!

Заключение

Выходит, что не получилось у Диска защитить мое «ценное» видео. Возможно, описанные выше действия не подойдут обычному пользователю, но и сложным процесс скачивания назвать нельзя.

Напомню, что возможность «защитить» свои файлы от копирования входит в платную подписку. Более того, об этой возможности явно заявляется, как о преимуществе, при сравнении платной и бесплатной версии Диска.

Информация к размышлению. Публичная ссылка работает сразу после нажатия на «Поделиться». При этом по умолчанию публичная ссылка бессрочна. Что будет с защитой от скачивания после прекращения действия подписки? Люди, у которых есть ссылка смогут скачать файлы?

Полезные ссылки


  1. Правая кнопка мыши ↩︎

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *