diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4be06da..c323b08 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
Changelog
=======
+### 1.5.4
+- Add info about number of audio channels.
+- Bugfix tracks (audio, video, subtitle) menu.
+- Experimental support for macOS 10.14.
+
### 1.5.3
- Bugfix for chapters.
@@ -24,9 +29,9 @@ Changelog
### 1.0.0
- Universal binary support (_but `ffmpeg` for arm64 is compiled on intel platform without assembly optimizations_).
-- Support for automatic Sparke update.
+- Support for automatic Sparkle update.
- New app icon.
-- Removed App Group capability to handle the settings (App Group _require_ codesign). Settings are now handled with an XPC service.
+- Removed App Group capability to handle the settings (App Group _require_ code sign). Settings are now handled with an XPC service.
### 1.0.b11
diff --git a/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_mono.imageset/Contents.json b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_mono.imageset/Contents.json
new file mode 100644
index 0000000..9733e5b
--- /dev/null
+++ b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_mono.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "filename" : "speaker_mono.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "preserves-vector-representation" : true,
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_mono.imageset/speaker_mono.pdf b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_mono.imageset/speaker_mono.pdf
new file mode 100644
index 0000000..b0789f0
Binary files /dev/null and b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_mono.imageset/speaker_mono.pdf differ
diff --git a/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_stereo.imageset/Contents.json b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_stereo.imageset/Contents.json
new file mode 100644
index 0000000..67581b9
--- /dev/null
+++ b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_stereo.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "filename" : "speaker_stereo.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "preserves-vector-representation" : true,
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_stereo.imageset/speaker_stereo.pdf b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_stereo.imageset/speaker_stereo.pdf
new file mode 100644
index 0000000..f22fe06
Binary files /dev/null and b/MediaInfo Finder Extension/Assets_menu.xcassets/speaker_stereo.imageset/speaker_stereo.pdf differ
diff --git a/MediaInfo Finder Extension/MediaInfo_Finder_Extension.entitlements b/MediaInfo Finder Extension/MediaInfo_Finder_Extension.entitlements
index 10d57e7..6e7e756 100644
--- a/MediaInfo Finder Extension/MediaInfo_Finder_Extension.entitlements
+++ b/MediaInfo Finder Extension/MediaInfo_Finder_Extension.entitlements
@@ -7,8 +7,6 @@
com.apple.security.files.user-selected.read-only
com.apple.security.temporary-exception.files.home-relative-path.read-only
-
- /
-
+
diff --git a/MediaInfo Finder Extension/it.lproj/LocalizableExt.strings b/MediaInfo Finder Extension/it.lproj/LocalizableExt.strings
index a076ab6..8d06959 100644
--- a/MediaInfo Finder Extension/it.lproj/LocalizableExt.strings
+++ b/MediaInfo Finder Extension/it.lproj/LocalizableExt.strings
@@ -95,3 +95,8 @@
"last saved by %@" = "ultimo salvataggio di %@";
"last saved on %@" = "ultimo salvataggio il %@";
"on %@" = "il %@";
+
+"mono" = "mono";
+"stereo" = "stereo";
+"1 channel" = "1 canale";
+"%d channels" = "%d canali";
diff --git a/MediaInfo.xcodeproj/project.pbxproj b/MediaInfo.xcodeproj/project.pbxproj
index 08f24d4..6fbccbd 100644
--- a/MediaInfo.xcodeproj/project.pbxproj
+++ b/MediaInfo.xcodeproj/project.pbxproj
@@ -11264,7 +11264,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
@@ -11281,7 +11281,8 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = org.sbarex.MediaInfo;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -11299,7 +11300,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
@@ -11316,7 +11317,8 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = org.sbarex.MediaInfo;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -11332,7 +11334,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_ASSET_PATHS = "MediaInfo\\ Finder\\ Extension/Assets_menu.xcassets";
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@@ -11347,7 +11349,8 @@
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = "org.sbarex.MediaInfo.Finder-Extension";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -11364,7 +11367,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_ASSET_PATHS = "MediaInfo\\ Finder\\ Extension/Assets_menu.xcassets";
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@@ -11379,7 +11382,8 @@
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = "org.sbarex.MediaInfo.Finder-Extension";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -11439,7 +11443,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
HEADER_SEARCH_PATHS = (
@@ -11459,7 +11463,8 @@
"$(BUILT_PRODUCTS_DIR)/libwebp",
"$(inherited)",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
PRODUCT_BUNDLE_IDENTIFIER = org.sbarex.MediaInfoHelperXPC;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -11477,7 +11482,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
HEADER_SEARCH_PATHS = (
@@ -11497,7 +11502,8 @@
"$(BUILT_PRODUCTS_DIR)/libwebp",
"$(inherited)",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = org.sbarex.MediaInfoHelperXPC;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -11514,7 +11520,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
HEADER_SEARCH_PATHS = (
@@ -11534,7 +11540,8 @@
"$(BUILT_PRODUCTS_DIR)/libwebp",
"$(inherited)",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
PRODUCT_BUNDLE_IDENTIFIER = org.sbarex.MediaInfoSettingsXPC;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -11550,7 +11557,7 @@
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 16;
+ CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
HEADER_SEARCH_PATHS = (
@@ -11570,7 +11577,8 @@
"$(BUILT_PRODUCTS_DIR)/libwebp",
"$(inherited)",
);
- MARKETING_VERSION = 1.5.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.14;
+ MARKETING_VERSION = 1.5.4;
OTHER_CODE_SIGN_FLAGS = "--timestamp";
PRODUCT_BUNDLE_IDENTIFIER = org.sbarex.MediaInfoSettingsXPC;
PRODUCT_NAME = "$(TARGET_NAME)";
diff --git a/MediaInfo/Assets.xcassets/speaker.imageset/Contents.json b/MediaInfo/Assets.xcassets/speaker.imageset/Contents.json
new file mode 100644
index 0000000..9733e5b
--- /dev/null
+++ b/MediaInfo/Assets.xcassets/speaker.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "filename" : "speaker_mono.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "preserves-vector-representation" : true,
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/MediaInfo/Assets.xcassets/speaker.imageset/speaker_mono.pdf b/MediaInfo/Assets.xcassets/speaker.imageset/speaker_mono.pdf
new file mode 100644
index 0000000..b0789f0
Binary files /dev/null and b/MediaInfo/Assets.xcassets/speaker.imageset/speaker_mono.pdf differ
diff --git a/MediaInfo/MenuItemEditor.swift b/MediaInfo/MenuItemEditor.swift
index a1c1eca..514d572 100644
--- a/MediaInfo/MenuItemEditor.swift
+++ b/MediaInfo/MenuItemEditor.swift
@@ -56,6 +56,9 @@ class MenuItemEditor: NSViewController {
Image(name: "size", title: NSLocalizedString("File size", comment: "")),
Image(name: "print", title: NSLocalizedString("Printer", comment: "")),
Image(name: "person", title: NSLocalizedString("Person", comment: "")),
+ Image(name: "speaker", title: NSLocalizedString("Speaker (mono or stereo)", comment: "")),
+ Image(name: "speaker_mono", title: NSLocalizedString("Speaker", comment: "")),
+ Image(name: "speaker_stereo", title: NSLocalizedString("Speakers", comment: "")),
Image.separator(),
Image(name: "color", title: NSLocalizedString("Color", comment: "")),
diff --git a/MediaInfo/Settings.swift b/MediaInfo/Settings.swift
index f2c92e0..b83b6ab 100644
--- a/MediaInfo/Settings.swift
+++ b/MediaInfo/Settings.swift
@@ -107,7 +107,7 @@ class Settings {
MenuItem(image: "size", template: "[[filesize]]"),
]
settings.audioMenuItems = [
- MenuItem(image: "audio", template: "[[duration]] ([[seconds]]) [[language-flag]]"),
+ MenuItem(image: "audio", template: "[[duration]] ([[seconds]]) [[channels-name]] [[language-flag]]"),
MenuItem(image: "audio", template: "[[bitrate]], [[codec]]"),
MenuItem(image: "tag", template: "[[title]]"),
MenuItem(image: "", template: "([[engine]])"),
diff --git a/MediaInfo/Tokens/TokenVideoMetadata.swift b/MediaInfo/Tokens/TokenVideoMetadata.swift
index f3c27f1..9e0530c 100644
--- a/MediaInfo/Tokens/TokenVideoMetadata.swift
+++ b/MediaInfo/Tokens/TokenVideoMetadata.swift
@@ -138,6 +138,8 @@ class TokenAudioMetadata: Token {
case encoder
case chapters
case chaptersCount
+ case channels
+ case channels_name
static var pasteboardType: NSPasteboard.PasteboardType {
return .MITokenAudioMetadata
@@ -149,6 +151,8 @@ class TokenAudioMetadata: Token {
case .encoder: return "encoder"
case .chaptersCount: return String(format: NSLocalizedString("%d Chapters", tableName: "LocalizableExt", comment: ""), 2)
case .chapters: return NSLocalizedString("Chapters list", comment: "")
+ case .channels: return NSLocalizedString("1 channel", tableName: "LocalizableExt", comment: "")
+ case .channels_name: return NSLocalizedString("mono", tableName: "LocalizableExt", comment: "")
}
}
@@ -158,6 +162,8 @@ class TokenAudioMetadata: Token {
case .encoder: return "[[encoder]]"
case .chaptersCount: return "[[chapters-count]]"
case .chapters: return "[[chapters]]"
+ case .channels: return "[[channels]]"
+ case .channels_name: return "[[channels-name]]"
}
}
@@ -167,6 +173,8 @@ class TokenAudioMetadata: Token {
case .encoder: return NSLocalizedString("Encoder.", comment: "")
case .chapters: return NSLocalizedString("List of chapters.", comment: "")
case .chaptersCount: return NSLocalizedString("Number of chapters.", comment: "")
+ case .channels: return NSLocalizedString("Number of channels.", comment: "")
+ case .channels_name: return NSLocalizedString("Mono, Stereo, or number of channels.", comment: "")
}
}
@@ -176,7 +184,8 @@ class TokenAudioMetadata: Token {
case "[[encoder]]": self = .encoder
case "[[chapters]]": self = .chapters
case "[[chapters-count]]": self = .chaptersCount
-
+ case "[[channels]]": self = .channels
+ case "[[channels-name]]": self = .channels_name
default: return nil
}
}
diff --git a/MediaInfo/ViewController.swift b/MediaInfo/ViewController.swift
index 755797c..310efd4 100644
--- a/MediaInfo/ViewController.swift
+++ b/MediaInfo/ViewController.swift
@@ -235,7 +235,7 @@ class ViewController: NSViewController {
isLossless: false,
chapters: [Chapter(title: "title1", start: 0, end: 200), Chapter(title: "title2", start: 201, end: 600)],
video: [], audio: [
- AudioTrackInfo(duration: 3600, start_time: 0, codec_short_name: "mp3", codec_long_name: "MP3 (MPEG audio layer 3)", lang: "EN", bitRate: 512*1025, title: "Audio title", encoder: "Encoder", isLossless: false)
+ AudioTrackInfo(duration: 3600, start_time: 0, codec_short_name: "mp3", codec_long_name: "MP3 (MPEG audio layer 3)", lang: "EN", bitRate: 512*1025, title: "Audio title", encoder: "Encoder", isLossless: false, channels: 2)
], subtitles: [
SubtitleTrackInfo(title: "English subtitle", lang: "EN"),
SubtitleTrackInfo(title: "Sottitoli in italiano", lang: "IT"),
@@ -265,6 +265,7 @@ class ViewController: NSViewController {
title: "Audio title", encoder: "Encoder",
isLossless: false,
chapters: [],
+ channels: 2,
engine: .coremedia)
}
diff --git a/MediaInfo/it.lproj/Localizable.strings b/MediaInfo/it.lproj/Localizable.strings
index 632feba..15c51ed 100644
--- a/MediaInfo/it.lproj/Localizable.strings
+++ b/MediaInfo/it.lproj/Localizable.strings
@@ -127,6 +127,8 @@
"sheets" = "fogli";
"Page size (for document files)." = "Dimensioni sulla pagina (per documenti di testo).";
"Page format or page size (for document files)." = "Formato pagina o sue dimensioni (per documenti di testo).";
+"Number of channels." = "Numero di canali";
+"Mono, Stereo, or number of channels." = "Mono, Stereo, o numbero di canali.";
// MARK: -
"Number of audio tracks." = "Numero di tracce audio.";
@@ -177,6 +179,9 @@
"PDF" = "PDF";
"Printer" = "Stampante";
"Person" = "Persona";
+"Speaker (mono or stereo)" = "Altoparlante (mono o stereo)";
+"Speaker" = "Altoparlante";
+"Speakers" = "Altoparlanti";
"Color" = "Colore";
"Black and White" = "Bianco e nero";
"Gray scale" = "Scala di grigio";
diff --git a/MediaInfoHelperXPC/CGMediaUtils.swift b/MediaInfoHelperXPC/CGMediaUtils.swift
index 79c0848..f2b53f2 100644
--- a/MediaInfoHelperXPC/CGMediaUtils.swift
+++ b/MediaInfoHelperXPC/CGMediaUtils.swift
@@ -258,6 +258,7 @@ func getCMMediaInfo(forFile file: URL) -> MediaInfo? {
encoder: encoder ?? a.encoder,
isLossless: a.isLossless,
chapters: chapters,
+ channels: a.channels,
engine: .coremedia
)
return audio
@@ -303,13 +304,20 @@ func getCMMediaStreams(forFile file: URL) -> [BaseInfo] {
let numberOfFrames = Int((durationInSeconds * framesPerSecond).rounded())
// let d = track.formatDescriptions.first as! CMVideoFormatDescription
let formatDescriptions = track.formatDescriptions as! [CMFormatDescription]
- let formatDesc = formatDescriptions.first
+ var mediaType: FourCharCode?
+ if let formatDesc = formatDescriptions.first {
+ if #available(macOS 10.15, *) {
+ mediaType = formatDesc.mediaSubType.rawValue
+ } else {
+ mediaType = CMFormatDescriptionGetMediaSubType(formatDesc)
+ }
+ }
let v = VideoTrackInfo(
width: Int(track.naturalSize.width), height: Int(track.naturalSize.height),
duration: durationInSeconds, start_time: startTime,
- codec_short_name: codecForVideoCode(formatDesc?.mediaSubType.rawValue) ?? "",
- codec_long_name: longCodecForVideoCode(formatDesc?.mediaSubType.rawValue),
+ codec_short_name: codecForVideoCode(mediaType) ?? "",
+ codec_long_name: longCodecForVideoCode(mediaType),
profile: nil,
pixel_format: nil, color_space: nil, field_order: nil,
lang: lang,
@@ -326,17 +334,30 @@ func getCMMediaStreams(forFile file: URL) -> [BaseInfo] {
let durationInSeconds = CMTimeGetSeconds(track.timeRange.duration)
let startTime = CMTimeGetSeconds(track.timeRange.start)
let formatDescriptions = track.formatDescriptions as! [CMFormatDescription]
- let formatDesc = formatDescriptions.first
+
+ var channels = -1
+ var mediaType: FourCharCode? = nil
+ if let formatDesc = formatDescriptions.first {
+ if let basic = CMAudioFormatDescriptionGetStreamBasicDescription(formatDesc) {
+ channels = Int(basic.pointee.mChannelsPerFrame)
+ }
+ if #available(macOS 10.15, *) {
+ mediaType = formatDesc.mediaSubType.rawValue
+ } else {
+ mediaType = CMFormatDescriptionGetMediaSubType(formatDesc)
+ }
+ }
let a = AudioTrackInfo(
duration: durationInSeconds, start_time: startTime,
- codec_short_name: codecForVideoCode(formatDesc?.mediaSubType.rawValue) ?? "",
- codec_long_name: longCodecForVideoCode(formatDesc?.mediaSubType.rawValue),
+ codec_short_name: codecForVideoCode(mediaType) ?? "",
+ codec_long_name: longCodecForVideoCode(mediaType),
lang: lang,
bitRate: Int64(track.estimatedDataRate),
title: title,
encoder: encoder,
- isLossless: nil
+ isLossless: nil,
+ channels: channels
)
streams.append(a)
diff --git a/MediaInfoHelperXPC/FFMpegMediaUtils.swift b/MediaInfoHelperXPC/FFMpegMediaUtils.swift
index 054a612..a1367a9 100644
--- a/MediaInfoHelperXPC/FFMpegMediaUtils.swift
+++ b/MediaInfoHelperXPC/FFMpegMediaUtils.swift
@@ -431,6 +431,7 @@ func getFFMpegAudioInfo(forFile file: URL) -> AudioInfo? {
title: title ?? a.title, encoder: encoder ?? a.encoder,
isLossless: a.isLossless,
chapters: chapters,
+ channels: a.channels,
engine: .ffmpeg
)
return audio
@@ -611,7 +612,8 @@ func getFFMpegMediaStreams(forFile file: URL, with pFormatCtx: inout UnsafeMutab
lang: lang,
bitRate: bit_rate,
title: title, encoder: encoder,
- isLossless: isLossless
+ isLossless: isLossless,
+ channels: Int(avctx!.pointee.channels)
)
streams.append(a)
diff --git a/MediaInfoHelperXPC/MetadataMediaUtils.swift b/MediaInfoHelperXPC/MetadataMediaUtils.swift
index 347c512..4350703 100644
--- a/MediaInfoHelperXPC/MetadataMediaUtils.swift
+++ b/MediaInfoHelperXPC/MetadataMediaUtils.swift
@@ -105,6 +105,7 @@ func getMetadataAudioInfo(forFile file: URL) -> AudioInfo? {
encoder: a.encoder,
isLossless: a.isLossless,
chapters: [],
+ channels: a.channels,
engine: .metadata
)
return audio
@@ -174,6 +175,12 @@ func getMetadataMediaStreams(forFile file: URL, withMetadata metadata: MDItem) -
CFNumberGetValue((n as! CFNumber), CFNumberType.sInt64Type, &audioBitRate)
}
+ var channels: Int = 0
+ if let n = MDItemCopyAttribute(metadata, kMDItemAudioChannelCount) {
+ CFNumberGetValue((n as! CFNumber), CFNumberType.sInt64Type, &channels)
+ }
+
+
for (i, type) in types.enumerated() {
let codec = i < codecs.count ? codecs[i] : ""
let lang = i < langs.count ? langs[i] : nil
@@ -193,16 +200,18 @@ func getMetadataMediaStreams(forFile file: URL, withMetadata metadata: MDItem) -
bitRate: videoBitRate, fps: 0,
frames: 0,
title: nil, encoder: nil,
- isLossless: nil)
+ isLossless: nil
+ )
streams.append(v)
case "Sound":
let a = AudioTrackInfo(
- duration: duration, start_time: -1,
- codec_short_name: codec, codec_long_name: nil,
- lang: lang,
- bitRate: audioBitRate,
- title: nil, encoder: nil,
- isLossless: nil
+ duration: duration, start_time: -1,
+ codec_short_name: codec, codec_long_name: nil,
+ lang: lang,
+ bitRate: audioBitRate,
+ title: nil, encoder: nil,
+ isLossless: nil,
+ channels: channels
)
streams.append(a)
default:
diff --git a/MediaInfoHelperXPC/info/BaseInfoItems.swift b/MediaInfoHelperXPC/info/BaseInfoItems.swift
index 688c24a..44ea7c0 100644
--- a/MediaInfoHelperXPC/info/BaseInfoItems.swift
+++ b/MediaInfoHelperXPC/info/BaseInfoItems.swift
@@ -89,6 +89,8 @@ class BaseInfo: NSCoding {
img = NSImage(named: "ppt")
case "abc":
img = NSImage(named: "abc")
+ case "speaker":
+ img = NSImage(named: "speaker_mono")
default:
img = NSImage(named: mode)
}
diff --git a/MediaInfoHelperXPC/info/MediaInfoItems.swift b/MediaInfoHelperXPC/info/MediaInfoItems.swift
index 098e850..eb151cb 100644
--- a/MediaInfoHelperXPC/info/MediaInfoItems.swift
+++ b/MediaInfoHelperXPC/info/MediaInfoItems.swift
@@ -1153,7 +1153,7 @@ class VideoInfo: VideoTrackInfo, MediaInfo, ChaptersInfo {
return s
case "[[audio-count]]":
let s = format(value: values?["audio"] ?? self.audioTracks, isFilled: &isFilled) { v, isFilled in
- guard let audio = v as? [AudioInfo] else {
+ guard let audio = v as? [AudioTrackInfo] else {
isFilled = false
return self.formatERR(useEmptyData: useEmptyData)
}
@@ -1240,16 +1240,15 @@ class VideoInfo: VideoTrackInfo, MediaInfo, ChaptersInfo {
let group_tracks = settings.isTracksGrouped // FIXME: rename
let video_sub_menu: NSMenu
+ var title = ""
if group_tracks {
var filled = false
- var title = self.replacePlaceholders(in: "[[video-count]]", settings: settings, isFilled: &filled)
+ title = self.replacePlaceholders(in: "[[video-count]]", settings: settings, isFilled: &filled)
if !filled || title.isEmpty {
title = NSLocalizedString("Video", tableName: "LocalizableExt", comment: "")
}
- let video_mnu = destination_sub_menu.addItem(withTitle: title, action: nil, keyEquivalent: "")
- video_mnu.image = self.getImage(for: "video")
video_sub_menu = NSMenu(title: title)
- destination_sub_menu.setSubmenu(video_sub_menu, for: video_mnu)
+
} else {
video_sub_menu = destination_sub_menu
}
@@ -1261,6 +1260,15 @@ class VideoInfo: VideoTrackInfo, MediaInfo, ChaptersInfo {
video_sub_menu.addItem(item.copy() as! NSMenuItem)
}
}
+ if group_tracks {
+ if n == 1 && settings.isInfoOnMainItem && video_sub_menu.items.count == 1 {
+ destination_sub_menu.addItem(video_sub_menu.items.first!.copy() as! NSMenuItem)
+ } else {
+ let video_mnu = destination_sub_menu.addItem(withTitle: title, action: nil, keyEquivalent: "")
+ video_mnu.image = self.getImage(for: "video")
+ destination_sub_menu.setSubmenu(video_sub_menu, for: video_mnu)
+ }
+ }
case "[[audio]]":
let n = audioTracks.count
guard n > 0 else {
@@ -1268,20 +1276,20 @@ class VideoInfo: VideoTrackInfo, MediaInfo, ChaptersInfo {
}
let audio_sub_menu: NSMenu
- let group_tracks = settings.isTracksGrouped // FIXME: rename
+ let group_tracks = settings.isTracksGrouped
+ var title = ""
if group_tracks {
var filled = false
- var title = self.replacePlaceholders(in: "[[audio-count]]", settings: settings, isFilled: &filled)
+ title = self.replacePlaceholders(in: "[[audio-count]]", settings: settings, isFilled: &filled)
if !filled || title.isEmpty {
title = NSLocalizedString("Audio", tableName: "LocalizableExt", comment: "")
}
- let audio_mnu = destination_sub_menu.addItem(withTitle: title, action: nil, keyEquivalent: "")
- audio_mnu.image = self.getImage(for: "audio")
+
audio_sub_menu = NSMenu(title: title)
- destination_sub_menu.setSubmenu(audio_sub_menu, for: audio_mnu)
} else {
audio_sub_menu = destination_sub_menu
}
+
for audio in audioTracks {
guard let audio_menu = audio.getMenu(withSettings: settings) else {
continue
@@ -1290,9 +1298,22 @@ class VideoInfo: VideoTrackInfo, MediaInfo, ChaptersInfo {
audio_sub_menu.addItem(item.copy() as! NSMenuItem)
}
}
+ if group_tracks {
+ if n == 1 && settings.isInfoOnMainItem && audio_sub_menu.items.count == 1 {
+ destination_sub_menu.addItem(audio_sub_menu.items.first!.copy() as! NSMenuItem)
+ } else {
+ let audio_mnu = destination_sub_menu.addItem(withTitle: title, action: nil, keyEquivalent: "")
+ audio_mnu.image = self.getImage(for: "audio")
+ destination_sub_menu.setSubmenu(audio_sub_menu, for: audio_mnu)
+ }
+ }
case "[[subtitles]]":
- let sub_menu_txt: NSMenu
let n = subtitles.count
+ guard n > 0 else {
+ return true
+ }
+
+ let sub_menu_txt: NSMenu
let group_tracks = settings.isTracksGrouped // FIXME: rename
if group_tracks {
let mnu_txt = destination_sub_menu.addItem(withTitle: "\(n) " + NSLocalizedString("Subtitles", tableName: "LocalizableExt", comment: ""), action: nil, keyEquivalent: "")
@@ -1390,8 +1411,15 @@ class AudioTrackInfo: BaseInfo, LanguageInfo, DurationInfo, CodecInfo {
let title: String?
let encoder: String?
let isLossless: Bool?
+ let channels: Int
+ var isMono: Bool {
+ return channels == 1
+ }
+ var isStereo: Bool {
+ return channels == 2
+ }
- init(duration: Double, start_time: Double, codec_short_name: String, codec_long_name: String?, lang: String?, bitRate: Int64, title: String?, encoder: String?, isLossless: Bool?) {
+ init(duration: Double, start_time: Double, codec_short_name: String, codec_long_name: String?, lang: String?, bitRate: Int64, title: String?, encoder: String?, isLossless: Bool?, channels: Int) {
self.duration = duration
self.start_time = start_time
self.codec_short_name = codec_short_name
@@ -1401,6 +1429,7 @@ class AudioTrackInfo: BaseInfo, LanguageInfo, DurationInfo, CodecInfo {
self.isLossless = isLossless
self.title = title
self.encoder = encoder
+ self.channels = channels
super.init()
}
@@ -1414,6 +1443,7 @@ class AudioTrackInfo: BaseInfo, LanguageInfo, DurationInfo, CodecInfo {
self.title = coder.decodeObject(forKey: "title") as? String
self.encoder = coder.decodeObject(forKey: "encoder") as? String
self.isLossless = coder.decodeObject(forKey: "isLossless") as? Bool
+ self.channels = coder.decodeInteger(forKey: "channels")
super.init(coder: coder)
}
@@ -1427,11 +1457,21 @@ class AudioTrackInfo: BaseInfo, LanguageInfo, DurationInfo, CodecInfo {
coder.encode(self.title, forKey: "title")
coder.encode(self.encoder, forKey: "encoder")
coder.encode(self.isLossless, forKey: "isLossless")
+ coder.encode(self.channels, forKey: "channels")
super.encode(with: coder)
}
+ override func getImage(for name: String) -> NSImage? {
+ if name == "speaker" && self.isStereo {
+ return super.getImage(for: "speaker_stereo");
+ } else {
+ return super.getImage(for: name)
+ }
+ }
+
override internal func processPlaceholder(_ placeholder: String, settings: Settings, values: [String : Any]? = nil, isFilled: inout Bool) -> String {
+ let useEmptyData = false
switch placeholder {
case "[[duration]]", "[[seconds]]", "[[bitrate]]", "[[start-time]]", "[[start-time-s]]":
return processDurationPlaceholder(placeholder, values: values, isFilled: &isFilled)
@@ -1443,6 +1483,39 @@ class AudioTrackInfo: BaseInfo, LanguageInfo, DurationInfo, CodecInfo {
"[[chapters-count]]", "[[engine]]":
isFilled = false
return ""
+ case "[[channels]]":
+ return format(value: values?["channels"] ?? self.channels, isFilled: &isFilled) { v, isFilled in
+ guard let channels = v as? Int else {
+ isFilled = false
+ return self.formatERR(useEmptyData: useEmptyData)
+ }
+ isFilled = channels > 0
+ if channels <= 0 {
+ return self.formatND(useEmptyData: useEmptyData)
+ } else if channels == 1 {
+ return NSLocalizedString("1 channel", tableName: "LocalizableExt", comment: "")
+ } else {
+ return String(format: NSLocalizedString("%d channels", tableName: "LocalizableExt", comment: ""), channels)
+ }
+ }
+
+ case "[[channels-name]]":
+ return format(value: values?["channels"] ?? self.channels, isFilled: &isFilled) { v, isFilled in
+ guard let channels = v as? Int else {
+ isFilled = false
+ return self.formatERR(useEmptyData: useEmptyData)
+ }
+ isFilled = channels > 0
+ if channels <= 0 {
+ return self.formatND(useEmptyData: useEmptyData)
+ } else if channels == 1 {
+ return NSLocalizedString("mono", tableName: "LocalizableExt", comment: "")
+ } else if channels == 2 {
+ return NSLocalizedString("stereo", tableName: "LocalizableExt", comment: "")
+ } else {
+ return String(format: NSLocalizedString("%d channels", tableName: "LocalizableExt", comment: ""), channels)
+ }
+ }
default:
return super.processPlaceholder(placeholder, settings: settings, values: values, isFilled: &isFilled)
}
@@ -1476,13 +1549,13 @@ class AudioInfo: AudioTrackInfo, MediaInfo, ChaptersInfo {
let chapters: [Chapter]
let engine: MediaEngine
- init(file: URL, duration: Double, start_time: Double, codec_short_name: String, codec_long_name: String?, lang: String?, bitRate: Int64, title: String?, encoder: String?, isLossless: Bool?, chapters: [Chapter], engine: MediaEngine) {
+ init(file: URL, duration: Double, start_time: Double, codec_short_name: String, codec_long_name: String?, lang: String?, bitRate: Int64, title: String?, encoder: String?, isLossless: Bool?, chapters: [Chapter], channels: Int, engine: MediaEngine) {
self.file = file
self.fileSize = Self.getFileSize(file) ?? -1
self.chapters = chapters
self.engine = engine
- super.init(duration: duration, start_time: start_time, codec_short_name: codec_short_name, codec_long_name: codec_long_name, lang: lang, bitRate: bitRate, title: title, encoder: encoder, isLossless: isLossless)
+ super.init(duration: duration, start_time: start_time, codec_short_name: codec_short_name, codec_long_name: codec_long_name, lang: lang, bitRate: bitRate, title: title, encoder: encoder, isLossless: isLossless, channels: channels)
}
required init?(coder: NSCoder) {
diff --git a/README.md b/README.md
index d6dac6e..196c981 100644
--- a/README.md
+++ b/README.md
@@ -183,6 +183,8 @@ Available information:
|codec|Codec name (full name if available, otherwise short name).|_MPEG audio layer 2/3_|
|codec short name|Codec short name.|_mp3_|
|codec long name|Codec long name.|_MPEG audio layer 2/3_|
+|channels|Number of channels|_2 channels_|
+|channels|Audio mono, stereo or number of channels|_Mono_, _Stereo_, _3 channels_, …|
|chapters|Number of chapters.|_2 chapters_ If this placeholder is the only in the menu item will be added a submenu with the list of the chapters.|
|title|Title.||
|encoder|Encoder.|_libffmpeg_|
diff --git a/buildffmpeg b/buildffmpeg
index 857616b..11a81c6 100755
--- a/buildffmpeg
+++ b/buildffmpeg
@@ -112,7 +112,7 @@ else
mkdir -p "${OUTDIR}"
if [[ "$ONLY_ACTIVE_ARCH" == "YES" ]]; then
if [[ "$NATIVE_ARCH" == "x86_64" ]]; then
- compile "${OUTDIR}/${CONFIGURATION}/${NATIVE_ARCH}" "-mmacosx-version-min=10.15 -DNDEBUG" "" ""
+ compile "${OUTDIR}/${CONFIGURATION}/${NATIVE_ARCH}" "-mmacosx-version-min=10.14 -DNDEBUG" "" ""
else
compile "${OUTDIR}/${CONFIGURATION}/${NATIVE_ARCH}" "-target arm64-apple-macos11 -DNDEBUG" "-target arm64-apple-macos11" "arm"
fi
@@ -132,7 +132,7 @@ else
exit $retVal
fi
else
- compile "${OUTDIR}/${CONFIGURATION}/x86_64" "-mmacosx-version-min=10.15 -DNDEBUG" "" "x86_64"
+ compile "${OUTDIR}/${CONFIGURATION}/x86_64" "-mmacosx-version-min=10.14 -DNDEBUG" "" "x86_64"
compile "${OUTDIR}/${CONFIGURATION}/arm64" "-target arm64-apple-macos11 -DNDEBUG" "-target arm64-apple-macos11" "arm64"
diff --git a/buildwebp b/buildwebp
index 6e7ebb2..9f02d18 100755
--- a/buildwebp
+++ b/buildwebp
@@ -104,7 +104,7 @@ else
if [[ "$ONLY_ACTIVE_ARCH" == "YES" ]]; then
if [[ "$NATIVE_ARCH" == "x86_64" ]]; then
- compile "${OUTDIR}/${CONFIGURATION}/x86_64" "-mmacosx-version-min=10.15 -DNDEBUG" "" ""
+ compile "${OUTDIR}/${CONFIGURATION}/x86_64" "-mmacosx-version-min=10.14 -DNDEBUG" "" ""
basename="${OUTDIR}/${CONFIGURATION}/x86_64/lib/"
else
@@ -121,7 +121,7 @@ else
fi
done
else
- compile "${OUTDIR}/${CONFIGURATION}/x86_64" "-mmacosx-version-min=10.15 -DNDEBUG" "" ""
+ compile "${OUTDIR}/${CONFIGURATION}/x86_64" "-mmacosx-version-min=10.14 -DNDEBUG" "" ""
compile "${OUTDIR}/${CONFIGURATION}/arm64" "-target arm64-apple-macos11 -DNDEBUG" "-target arm64-apple-macos11" "arm"
diff --git a/docs/appcast.xml b/docs/appcast.xml
index 8c66396..9226ee3 100644
--- a/docs/appcast.xml
+++ b/docs/appcast.xml
@@ -60,7 +60,7 @@
1.5.3
lun, 31 Mag 2021 15:53:12 +0100
10.15
-
+
Bugfix for chapters.
@@ -68,5 +68,19 @@
]]>
+ -
+ 1.5.4
+ mar, 1 Giu 2021 19:16:12 +0100
+ 10.14
+
+
+ Add info about number of audio channels.
+ Bugfix tracks (audio, video, subtitle) menu.
+ Experimental support for macOS 10.14.
+
+ ]]>
+
+