Determine if image picker media type is video
Asked Answered
I

2

7

I've seen various methods for checking whether the returned media type in -imagePickerController:didFinishPickingMediaWithInfo: is video. For example, my way:

- (void)imagePickerController:(UIImagePickerController *)imagePicker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    if (UTTypeEqual(kUTTypeMovie, 
    (__bridge CFStringRef)[info objectForKey:UIImagePickerControllerMediaType])) 
    {
        // ...
    }
}

or

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {

or

if ([mediaType isEqualToString:(NSString *)kUTTypeVideo] || 
    [mediaType isEqualToString:(NSString *)kUTTypeMovie])

or

if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
        == kCFCompareEqualTo) 

or

if ([mediaType isEqualToString:@"public.movie"]

Everyone seems to have a different way of doing this. What's the recommended method for checking the media type? Preferably with a way to include "all image types" or "all video types".

Iqbal answered 25/3, 2013 at 16:15 Comment(0)
F
16

It would be better to check for conformance with a particular UTI instead.

Right now, iOS tells you its a public.movie, but what will it say next year? You'll see people checking for public.video as well. Great, so you've hard-coded two types instead of one.

But wouldn't it be better to ask "Is this a movie?" rather than hard code the specific type you think iOS will return? There's a way to do that:

NSString *mediaType = info[UIImagePickerControllerMediaType];
BOOL isMovie = UTTypeConformsTo((__bridge CFStringRef)mediaType,
                                kUTTypeMovie) != 0;

Using this approach, isMovie should be YES if a movie is returned (regardless of which specific type is returned) if mediaType represents a movie, since all movies conform from kUTTypeMovie. To be really clear, if it is a kUTTypeVideo this will also recognize it as a movie, because kUTTypeVideo conforms to kUTTypeMovie.

Likewise, you can check for to see if the thing returned is an image:

NSString *mediaType = info[UIImagePickerControllerMediaType];
BOOL isImage = UTTypeConformsTo((__bridge CFStringRef)mediaType,
                                kUTTypeImage) != 0;

isIamge should be YES if an image is returned, since all images conform to kUTTypeImage.

See Apple's (partial) type tree here: Uniform Type Identifiers Are Declared in a Conformance Hierarchy. You can get a less useful but more complete list of all UTIs currently recognized by your system and their conformance from the shell with:

/System/Library/Frameworks/CoreServices.framework/Frameworks\
/LaunchServices.framework/Versions/A/Support/lsregister -dump

In particular, you can see public.video is defined like this:

--------------------------------------------------------
type    id:            8344
    uti:           public.video
    description:   video
    flags:         exported  active  core  apple-internal  trusted  
    icon:          
    conforms to:   public.movie
    tags:          
--------------------------------------------------------

Note that UTTypeConformsTo returns true if the types are the same as well. From Apple's docs:

Returns true if the uniform type identifier is equal to or conforms to the second type.

Foolish answered 31/3, 2015 at 20:1 Comment(3)
Not sure how this sat here without any up votes for so long. This is the best approach I've seen on SO.Family
I like your approach too. Thx a lot for this solution.Avictor
Once you stumble over these APIs, it's really the only one that makes any sense at all. :)Foolish
P
2

I would say the difference between the first method UTTypeEqual and the second and third methods (NSString comparison), is a matter of preference in dealing with CFStringRefs or NSStrings.

The 4th type appears to be referencing kUTTypeMovie by its actual string value which you should absolutely not do as it is private and may actually change. Aside from that it is just like the second and third methods.

It does look like you'll probably want to check against a few more types depending on how thorough you want/need to be.

I would probably check for kUTTypeAudiovisualContent, KUTTypeMovie, KUTTypeVideo, kUTTypeQuickTimeMovie, kUTTypeMPEG, kUTTypeMPEG4.

Full list from UTType Reference

kUTTypeAudiovisualContent
An abstract type identifier for audio and/or video content.
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeMovie
An abstract type identifier for a media format which may contain both video and audio. Corresponds to what users would label a "movie"
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeVideo
An abstract type identifier for pure video data(no audio).
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeAudio
An abstract type identifier for pure audio data (no video).
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeQuickTimeMovie
The type identifier for a QuickTime movie.
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeMPEG
The type identifier for a MPEG-1 or MPEG-2 movie.
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeMPEG4
The type identifier for a MPEG-4 movie.
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeMP3
The type identifier for MP3 audio.
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeMPEG4Audio
The type identifier for a MPEG-4 audio layer (.m4a, or the MIME type audio/MP4).
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.

kUTTypeAppleProtectedMPEG4Audio
The type identifier for Apple protected MPEG4 format (.m4p, iTunes music store format).
Available in iOS 3.0 and later.
Declared in UTCoreTypes.h.
Pedo answered 7/3, 2014 at 9:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.