Вопрос:
У меня есть требование, когда мне нужно извлечь метаданные из HLS Stream в Android. Я нашел две библиотеки FFMPEG и VITAMIO. Учитывая фрагментарную поддержку потоковой передачи HLS на Android и после чтения множества еще более запутанных статей, я завершил работу над этими двумя библиотеками для дальнейших исследований. Я не нашел ни одного приложения, в котором извлечение метаданных (timed metadata) было сделанный на Android.
Я смущен, если это возможно даже на Android. И если да, то какой подход я должен использовать…
помогите мне парням….
Лучший ответ:
Временные текстовые метаданные не сохраняются в файле m3u8, как было предложено Николасом, но вместо этого сохраняются в сегментах mpeg2 ts. Обзор того, как он встроен в ts, доступен здесь:
Вы можете попробовать извлечь метаданные с помощью ffmpeg, команда должна быть чем-то вроде этого:
ffmpeg -i in.ts -f ffmetadata metadata.txt
Вам нужно будет сделать эквивалент, используя jni и libavformat. Это не невероятно просто, и вам все равно придется придумать механизм передачи прочитанных метаданных вашему приложению.
Если вы можете, я бы порекомендовал сигнализировать приложенные метаданные через отдельный механизм. Не могли бы вы его извлечь и разместить в виде текстового файла, который ваш плеер загружает отдельно? Затем вы устанавливаете график времени, о котором сообщает видеоплеер? Это было бы намного проще реализовать, но я не знаю ваших требований.
Ответ №1
Разбор m3u8 относительно прост. Вам нужно создать HashMap из String и Integer для хранения проанализированных данных. Файл M3U8 состоит из 3 тегов ввода, которые представляют запись m3u8, медиапоследовательность и продолжительность сегмента всех медиафайлов, кроме последней, которая отличается от остальных.
После каждого прилипания к ней #EXTINF, поэтому нам нужно получить это, проанализировав строку с помощью основного регулярного выражения.
private HashMap<String, Integer> parseHLSMetadata(InputStream i ){ try { BufferedReader r = new BufferedReader(new InputStreamReader(i, «UTF-8»)); String line; HashMap<String, Integer> segmentsMap = null; String digitRegex = «\d+»; Pattern p = Pattern.compile(digitRegex); while((line = r.readLine())!=null){ if(line.equals(«#EXTM3U»)){ //start of m3u8 segmentsMap = new HashMap<String, Integer>(); }else if(line.contains(«#EXTINF»)){ //once found EXTINFO use runner to get the next line which contains the media file, parse duration of the segment Matcher matcher = p.matcher(line); matcher.find(); //find the first matching digit, which represents the duration of the segment, dont call .find() again that will throw digit which may be contained in the description. segmentsMap.put(r.readLine(), Integer.parseInt(matcher.group(0))); } } r.close(); return segmentsMap; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
Приветствия.