implement chapters in media information object, fixes #196

This commit is contained in:
Taner Sener 2021-11-10 23:34:18 +00:00
parent eee5917746
commit a7fe2d4b66
15 changed files with 539 additions and 35 deletions

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
package com.arthenica.ffmpegkit;
import org.json.JSONObject;
public class Chapter {
/* KEYS */
public static final String KEY_ID = "id";
public static final String KEY_TIME_BASE = "time_base";
public static final String KEY_START = "start";
public static final String KEY_START_TIME = "start_time";
public static final String KEY_END = "end";
public static final String KEY_END_TIME = "end_time";
public static final String KEY_TAGS = "tags";
private final JSONObject jsonObject;
public Chapter(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}
public Long getId() {
return getNumberProperty(KEY_ID);
}
public String getTimeBase() {
return getStringProperty(KEY_TIME_BASE);
}
public Long getStart() {
return getNumberProperty(KEY_START);
}
public String getStartTime() {
return getStringProperty(KEY_START_TIME);
}
public Long getEnd() {
return getNumberProperty(KEY_END);
}
public String getEndTime() {
return getStringProperty(KEY_END_TIME);
}
public JSONObject getTags() {
return getProperties(KEY_TAGS);
}
/**
* Returns the chapter property associated with the key.
*
* @param key property key
* @return chapter property as string or null if the key is not found
*/
public String getStringProperty(final String key) {
JSONObject chapterProperties = getAllProperties();
if (chapterProperties == null) {
return null;
}
if (chapterProperties.has(key)) {
return chapterProperties.optString(key);
} else {
return null;
}
}
/**
* Returns the chapter property associated with the key.
*
* @param key property key
* @return chapter property as Long or null if the key is not found
*/
public Long getNumberProperty(String key) {
JSONObject chapterProperties = getAllProperties();
if (chapterProperties == null) {
return null;
}
if (chapterProperties.has(key)) {
return chapterProperties.optLong(key);
} else {
return null;
}
}
/**
* Returns the chapter properties associated with the key.
*
* @param key properties key
* @return chapter properties as a JSONObject or null if the key is not found
*/
public JSONObject getProperties(String key) {
JSONObject chapterProperties = getAllProperties();
if (chapterProperties == null) {
return null;
}
return chapterProperties.optJSONObject(key);
}
/**
* Returns all chapter properties defined.
*
* @return all chapter properties as a JSONObject or null if no properties are defined
*/
public JSONObject getAllProperties() {
return jsonObject;
}
}

View File

@ -52,6 +52,16 @@ public class FFprobeKit {
private FFprobeKit() {
}
/**
* <p>Builds the default command used to get media information for a file.
*
* @param path file path to use in the command
* @return default command arguments to get media information
*/
private static String[] defaultGetMediaInformationCommandArguments(final String path) {
return new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-show_chapters", "-i", path};
}
/**
* <p>Synchronously executes FFprobe with arguments provided.
*
@ -249,7 +259,7 @@ public class FFprobeKit {
* @return media information session created for this execution
*/
public static MediaInformationSession getMediaInformation(final String path) {
final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path});
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path));
FFmpegKitConfig.getMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -265,7 +275,7 @@ public class FFprobeKit {
*/
public static MediaInformationSession getMediaInformation(final String path,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path});
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path));
FFmpegKitConfig.getMediaInformationExecute(session, waitTimeout);
@ -284,7 +294,7 @@ public class FFprobeKit {
*/
public static MediaInformationSession getMediaInformationAsync(final String path,
final ExecuteCallback executeCallback) {
final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback);
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -307,7 +317,7 @@ public class FFprobeKit {
final ExecuteCallback executeCallback,
final LogCallback logCallback,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback, logCallback);
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, waitTimeout);
@ -328,7 +338,7 @@ public class FFprobeKit {
public static MediaInformationSession getMediaInformationAsync(final String path,
final ExecuteCallback executeCallback,
final ExecutorService executorService) {
final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback);
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, executorService, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -353,7 +363,7 @@ public class FFprobeKit {
final LogCallback logCallback,
final ExecutorService executorService,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback, logCallback);
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, executorService, waitTimeout);

View File

@ -49,9 +49,15 @@ public class MediaInformation {
*/
private final List<StreamInformation> streams;
public MediaInformation(final JSONObject jsonObject, final List<StreamInformation> streams) {
/**
* Stores chapters.
*/
private final List<Chapter> chapters;
public MediaInformation(final JSONObject jsonObject, final List<StreamInformation> streams, final List<Chapter> chapters) {
this.jsonObject = jsonObject;
this.streams = streams;
this.chapters = chapters;
}
/**
@ -135,6 +141,15 @@ public class MediaInformation {
return streams;
}
/**
* Returns all chapters.
*
* @return list of chapters
*/
public List<Chapter> getChapters() {
return chapters;
}
/**
* Returns the media property associated with the key.
*

View File

@ -34,6 +34,9 @@ import java.util.ArrayList;
*/
public class MediaInformationJsonParser {
public static final String KEY_STREAMS = "streams";
public static final String KEY_CHAPTERS = "chapters";
/**
* Extracts <code>MediaInformation</code> from the given FFprobe json output. Note that this
* method does not throw {@link JSONException} as {@link #fromWithError(String)} does and
@ -59,18 +62,27 @@ public class MediaInformationJsonParser {
* @throws JSONException if a parsing error occurs
*/
public static MediaInformation fromWithError(final String ffprobeJsonOutput) throws JSONException {
JSONObject jsonObject = new JSONObject(ffprobeJsonOutput);
JSONArray streamArray = jsonObject.optJSONArray("streams");
final JSONObject jsonObject = new JSONObject(ffprobeJsonOutput);
final JSONArray streamArray = jsonObject.optJSONArray(KEY_STREAMS);
final JSONArray chapterArray = jsonObject.optJSONArray(KEY_CHAPTERS);
ArrayList<StreamInformation> arrayList = new ArrayList<>();
ArrayList<StreamInformation> streamList = new ArrayList<>();
for (int i = 0; streamArray != null && i < streamArray.length(); i++) {
JSONObject streamObject = streamArray.optJSONObject(i);
if (streamObject != null) {
arrayList.add(new StreamInformation(streamObject));
streamList.add(new StreamInformation(streamObject));
}
}
return new MediaInformation(jsonObject, arrayList);
ArrayList<Chapter> chapterList = new ArrayList<>();
for (int i = 0; chapterArray != null && i < chapterArray.length(); i++) {
JSONObject chapterObject = chapterArray.optJSONObject(i);
if (chapterObject != null) {
chapterList.add(new Chapter(chapterObject));
}
}
return new MediaInformation(jsonObject, streamList, chapterList);
}
}

View File

@ -211,7 +211,7 @@ public class StreamInformation {
/**
* Returns all tags.
*
* @return tags dictionary
* @return tags object
*/
public JSONObject getTags() {
return getProperties(KEY_TAGS);

View File

@ -72,6 +72,85 @@ public class FFmpegKitTest {
" }\n" +
" }\n" +
" ],\n" +
" \"chapters\": [\n" +
" {\n" +
" \"id\": 0,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 0,\n" +
" \"start_time\": \"0.000000\",\n" +
" \"end\": 11158238,\n" +
" \"end_time\": \"506.042540\",\n" +
" \"tags\": {\n" +
" \"title\": \"1 Laying Plans - 2 Waging War\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": 1,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 11158238,\n" +
" \"start_time\": \"506.042540\",\n" +
" \"end\": 21433051,\n" +
" \"end_time\": \"972.020454\",\n" +
" \"tags\": {\n" +
" \"title\": \"3 Attack By Stratagem - 4 Tactical Dispositions\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 21433051,\n" +
" \"start_time\": \"972.020454\",\n" +
" \"end\": 35478685,\n" +
" \"end_time\": \"1609.010658\",\n" +
" \"tags\": {\n" +
" \"title\": \"5 Energy - 6 Weak Points and Strong\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": 3,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 35478685,\n" +
" \"start_time\": \"1609.010658\",\n" +
" \"end\": 47187043,\n" +
" \"end_time\": \"2140.001950\",\n" +
" \"tags\": {\n" +
" \"title\": \"7 Maneuvering - 8 Variation in Tactics\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": 4,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 47187043,\n" +
" \"start_time\": \"2140.001950\",\n" +
" \"end\": 66635594,\n" +
" \"end_time\": \"3022.022404\",\n" +
" \"tags\": {\n" +
" \"title\": \"9 The Army on the March - 10 Terrain\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": 5,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 66635594,\n" +
" \"start_time\": \"3022.022404\",\n" +
" \"end\": 83768105,\n" +
" \"end_time\": \"3799.007029\",\n" +
" \"tags\": {\n" +
" \"title\": \"11 The Nine Situations\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": 6,\n" +
" \"time_base\": \"1/22050\",\n" +
" \"start\": 83768105,\n" +
" \"start_time\": \"3799.007029\",\n" +
" \"end\": 95659008,\n" +
" \"end_time\": \"4338.277007\",\n" +
" \"tags\": {\n" +
" \"title\": \"12 The Attack By Fire - 13 The Use of Spies\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"format\": {\n" +
" \"filename\": \"sample.mp3\",\n" +
" \"nb_streams\": 1,\n" +
@ -459,6 +538,11 @@ public class FFmpegKitTest {
Assert.assertNotNull(mediaInformation.getStreams());
Assert.assertEquals(1, mediaInformation.getStreams().size());
assertAudioStream(mediaInformation.getStreams().get(0), 0L, "mp3", "MP3 (MPEG audio layer 3)", "44100", "stereo", "fltp", "320000");
Assert.assertNotNull(mediaInformation.getChapters());
Assert.assertEquals(7, mediaInformation.getChapters().size());
assertChapter(mediaInformation.getChapters().get(0), 0L, "1/22050", 0L, "0.000000", 11158238L, "506.042540");
assertChapter(mediaInformation.getChapters().get(1), 1L, "1/22050", 11158238L, "506.042540", 21433051L, "972.020454");
}
@Test
@ -743,4 +827,18 @@ public class FFmpegKitTest {
Assert.assertEquals(codecTimeBase, streamInformation.getCodecTimeBase());
}
private void assertChapter(Chapter chapter, Long id, String timeBase, Long start, String startTime, Long end, String endTime) {
Assert.assertEquals(id, chapter.getId());
Assert.assertEquals(timeBase, chapter.getTimeBase());
Assert.assertEquals(start, chapter.getStart());
Assert.assertEquals(startTime, chapter.getStartTime());
Assert.assertEquals(end, chapter.getEnd());
Assert.assertEquals(endTime, chapter.getEndTime());
Assert.assertNotNull(chapter.getTags());
Assert.assertEquals(1, chapter.getTags().length());
}
}

84
apple/src/Chapter.h Normal file
View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FFMPEG_KIT_CHAPTER_H
#define FFMPEG_KIT_CHAPTER_H
#import <Foundation/Foundation.h>
extern NSString* const ChapterKeyId;
extern NSString* const ChapterKeyTimeBase;
extern NSString* const ChapterKeyStart;
extern NSString* const ChapterKeyStartTime;
extern NSString* const ChapterKeyEnd;
extern NSString* const ChapterKeyEndTime;
extern NSString* const ChapterKeyTags;
/**
* Chapter class.
*/
@interface Chapter : NSObject
- (instancetype)init:(NSDictionary*)chapterDictionary;
- (NSNumber*)getId;
- (NSString*)getTimeBase;
- (NSNumber*)getStart;
- (NSString*)getStartTime;
- (NSNumber*)getEnd;
- (NSString*)getEndTime;
- (NSDictionary*)getTags;
/**
* Returns the chapter property associated with the key.
*
* @return chapter property as string or nil if the key is not found
*/
- (NSString*)getStringProperty:(NSString*)key;
/**
* Returns the chapter property associated with the key.
*
* @return chapter property as number or nil if the key is not found
*/
- (NSNumber*)getNumberProperty:(NSString*)key;
/**
* Returns the chapter properties associated with the key.
*
* @return chapter properties in a dictionary or nil if the key is not found
*/
- (NSDictionary*)getProperties:(NSString*)key;
/**
* Returns all chapter properties defined.
*
* @return all chapter properties in a dictionary or nil if no properties are defined
*/
- (NSDictionary*)getAllProperties;
@end
#endif // FFMPEG_KIT_CHAPTER_H

107
apple/src/Chapter.m Normal file
View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
#import "Chapter.h"
NSString* const ChapterKeyId = @"id";
NSString* const ChapterKeyTimeBase = @"time_base";
NSString* const ChapterKeyStart = @"start";
NSString* const ChapterKeyStartTime = @"start_time";
NSString* const ChapterKeyEnd = @"end";
NSString* const ChapterKeyEndTime = @"end_time";
NSString* const ChapterKeyTags = @"tags";
@implementation Chapter {
/**
* Stores all properties.
*/
NSDictionary *dictionary;
}
- (instancetype)init:(NSDictionary*)chapterDictionary {
self = [super init];
if (self) {
dictionary = chapterDictionary;
}
return self;
}
- (NSNumber*)getId {
return [self getNumberProperty:ChapterKeyId];
}
- (NSString*)getTimeBase {
return [self getStringProperty:ChapterKeyTimeBase];
}
- (NSNumber*)getStart {
return [self getNumberProperty:ChapterKeyStart];
}
- (NSString*)getStartTime {
return [self getStringProperty:ChapterKeyStartTime];
}
- (NSNumber*)getEnd {
return [self getNumberProperty:ChapterKeyEnd];
}
- (NSString*)getEndTime {
return [self getStringProperty:ChapterKeyEndTime];
}
- (NSDictionary*)getTags {
return [self getProperties:ChapterKeyTags];
}
- (NSString*)getStringProperty:(NSString*)key {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return allProperties[key];
}
- (NSNumber*)getNumberProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getAllProperties];
if (mediaProperties == nil) {
return nil;
}
return mediaProperties[key];
}
- (NSDictionary*)getProperties:(NSString*)key {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return allProperties[key];
}
- (NSDictionary*)getAllProperties {
return dictionary;
}
@end

View File

@ -28,6 +28,10 @@
[FFmpegKitConfig class];
}
+ (NSArray*)defaultGetMediaInformationCommandArguments:(NSString*)path {
return [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-show_chapters", @"-i", path, nil];
}
+ (FFprobeSession*)executeWithArguments:(NSArray*)arguments {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments];
[FFmpegKitConfig ffprobeExecute:session];
@ -89,42 +93,42 @@
}
+ (MediaInformationSession*)getMediaInformation:(NSString*)path {
NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformation:(NSString*)path withTimeout:(int)waitTimeout {
NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback {
NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback withLogCallback:(LogCallback)logCallback withTimeout:(int)waitTimeout {
NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback onDispatchQueue:(dispatch_queue_t)queue {
NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue withTimeout:(int)waitTimeout {
NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:waitTimeout];
return session;

View File

@ -6,6 +6,7 @@ libffmpegkit_la_SOURCES = \
AbstractSession.m \
ArchDetect.m \
AtomicLong.m \
Chapter.m \
FFmpegKit.m \
FFmpegKitConfig.m \
FFmpegSession.m \
@ -35,6 +36,7 @@ include_HEADERS = \
AbstractSession.h \
ArchDetect.h \
AtomicLong.h \
Chapter.h \
ExecuteCallback.h \
FFmpegKit.h \
FFmpegKitConfig.h \

View File

@ -134,18 +134,18 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libffmpegkit_la_DEPENDENCIES =
am__libffmpegkit_la_SOURCES_DIST = AbstractSession.m ArchDetect.m \
AtomicLong.m FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m \
FFprobeKit.m FFprobeSession.m Log.m MediaInformation.m \
MediaInformationJsonParser.m MediaInformationSession.m \
Packages.m ReturnCode.m Statistics.m StreamInformation.m \
ffmpegkit_exception.m fftools_cmdutils.c fftools_ffmpeg.c \
fftools_ffmpeg_filter.c fftools_ffmpeg_hw.c \
AtomicLong.m Chapter.m FFmpegKit.m FFmpegKitConfig.m \
FFmpegSession.m FFprobeKit.m FFprobeSession.m Log.m \
MediaInformation.m MediaInformationJsonParser.m \
MediaInformationSession.m Packages.m ReturnCode.m Statistics.m \
StreamInformation.m ffmpegkit_exception.m fftools_cmdutils.c \
fftools_ffmpeg.c fftools_ffmpeg_filter.c fftools_ffmpeg_hw.c \
fftools_ffmpeg_opt.c fftools_ffprobe.c \
fftools_ffmpeg_videotoolbox.c
@FFMPEGKIT_VIDEOTOOLBOX_TRUE@am__objects_1 = libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo
am_libffmpegkit_la_OBJECTS = libffmpegkit_la-AbstractSession.lo \
libffmpegkit_la-ArchDetect.lo libffmpegkit_la-AtomicLong.lo \
libffmpegkit_la-FFmpegKit.lo \
libffmpegkit_la-Chapter.lo libffmpegkit_la-FFmpegKit.lo \
libffmpegkit_la-FFmpegKitConfig.lo \
libffmpegkit_la-FFmpegSession.lo libffmpegkit_la-FFprobeKit.lo \
libffmpegkit_la-FFprobeSession.lo libffmpegkit_la-Log.lo \
@ -189,6 +189,7 @@ am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo \
./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo \
./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo \
./$(DEPDIR)/libffmpegkit_la-Chapter.Plo \
./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo \
./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo \
./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo \
@ -401,8 +402,8 @@ top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libffmpegkit.la
libffmpegkit_la_LIBADD = @FFMPEG_FRAMEWORKS@
libffmpegkit_la_SOURCES = AbstractSession.m ArchDetect.m AtomicLong.m \
FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m FFprobeKit.m \
FFprobeSession.m Log.m MediaInformation.m \
Chapter.m FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m \
FFprobeKit.m FFprobeSession.m Log.m MediaInformation.m \
MediaInformationJsonParser.m MediaInformationSession.m \
Packages.m ReturnCode.m Statistics.m StreamInformation.m \
ffmpegkit_exception.m fftools_cmdutils.c fftools_ffmpeg.c \
@ -412,6 +413,7 @@ include_HEADERS = \
AbstractSession.h \
ArchDetect.h \
AtomicLong.h \
Chapter.h \
ExecuteCallback.h \
FFmpegKit.h \
FFmpegKitConfig.h \
@ -521,6 +523,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-Chapter.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo@am__quote@ # am--include-marker
@ -667,6 +670,13 @@ libffmpegkit_la-AtomicLong.lo: AtomicLong.m
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -c -o libffmpegkit_la-AtomicLong.lo `test -f 'AtomicLong.m' || echo '$(srcdir)/'`AtomicLong.m
libffmpegkit_la-Chapter.lo: Chapter.m
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -MT libffmpegkit_la-Chapter.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-Chapter.Tpo -c -o libffmpegkit_la-Chapter.lo `test -f 'Chapter.m' || echo '$(srcdir)/'`Chapter.m
@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-Chapter.Tpo $(DEPDIR)/libffmpegkit_la-Chapter.Plo
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ $(AM_V_OBJC)source='Chapter.m' object='libffmpegkit_la-Chapter.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -c -o libffmpegkit_la-Chapter.lo `test -f 'Chapter.m' || echo '$(srcdir)/'`Chapter.m
libffmpegkit_la-FFmpegKit.lo: FFmpegKit.m
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -MT libffmpegkit_la-FFmpegKit.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-FFmpegKit.Tpo -c -o libffmpegkit_la-FFmpegKit.lo `test -f 'FFmpegKit.m' || echo '$(srcdir)/'`FFmpegKit.m
@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-FFmpegKit.Tpo $(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo
@ -922,6 +932,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-Chapter.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo
@ -991,6 +1002,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-Chapter.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo

View File

@ -21,6 +21,7 @@
#define FFMPEG_KIT_MEDIA_INFORMATION_H
#import <Foundation/Foundation.h>
#import "Chapter.h"
#import "StreamInformation.h"
extern NSString* const MediaKeyMediaProperties;
@ -38,7 +39,7 @@ extern NSString* const MediaKeyTags;
*/
@interface MediaInformation : NSObject
- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams;
- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams withChapters:(NSArray*)chapters;
/**
* Returns file name.
@ -103,6 +104,13 @@ extern NSString* const MediaKeyTags;
*/
- (NSArray*)getStreams;
/**
* Returns all chapters.
*
* @return chapters array
*/
- (NSArray*)getChapters;
/**
* Returns the media property associated with the key.
*

View File

@ -41,13 +41,19 @@ NSString* const MediaKeyTags = @"tags";
*/
NSArray *streamArray;
/**
* Stores chapters.
*/
NSArray *chapterArray;
}
- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams{
- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams withChapters:(NSArray*)chapters{
self = [super init];
if (self) {
dictionary = mediaDictionary;
streamArray = streams;
chapterArray = chapters;
}
return self;
@ -89,6 +95,10 @@ NSString* const MediaKeyTags = @"tags";
return streamArray;
}
- (NSArray*)getChapters {
return chapterArray;
}
- (NSString*)getStringProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getMediaProperties];
if (mediaProperties == nil) {

View File

@ -19,6 +19,9 @@
#import "MediaInformationJsonParser.h"
NSString* const MediaInformationJsonParserKeyStreams = @"streams";
NSString* const MediaInformationJsonParserKeyChapters = @"chapters";
@implementation MediaInformationJsonParser
+ (MediaInformation*)from:(NSString*)ffprobeJsonOutput {
@ -40,14 +43,21 @@
return nil;
}
NSArray* array = [jsonDictionary objectForKey:@"streams"];
NSArray* jsonStreamArray = [jsonDictionary objectForKey:MediaInformationJsonParserKeyStreams];
NSMutableArray *streamArray = [[NSMutableArray alloc] init];
for(int i = 0; i<array.count; i++) {
NSDictionary *streamDictionary = [array objectAtIndex:i];
for(int i = 0; i<jsonStreamArray.count; i++) {
NSDictionary *streamDictionary = [jsonStreamArray objectAtIndex:i];
[streamArray addObject:[[StreamInformation alloc] init:streamDictionary]];
}
return [[MediaInformation alloc] init:jsonDictionary withStreams:streamArray];
NSArray* jsonChapterArray = [jsonDictionary objectForKey:MediaInformationJsonParserKeyChapters];
NSMutableArray *chapterArray = [[NSMutableArray alloc] init];
for(int i = 0; i<jsonChapterArray.count; i++) {
NSDictionary *chapterDictionary = [jsonChapterArray objectAtIndex:i];
[chapterArray addObject:[[Chapter alloc] init:chapterDictionary]];
}
return [[MediaInformation alloc] init:jsonDictionary withStreams:streamArray withChapters:chapterArray];
}
@end

View File

@ -831,6 +831,7 @@ framework module ffmpegkit {
header "AbstractSession.h"
header "ArchDetect.h"
header "AtomicLong.h"
header "Chapter.h"
header "ExecuteCallback.h"
header "FFmpegKit.h"
header "FFmpegKitConfig.h"