Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
VideoLAN
VLC-iOS
Commits
ffc3b9ab
Commit
ffc3b9ab
authored
Apr 11, 2015
by
Felix Paul Kühne
Browse files
playback: split any non-UI logic from the view controller to a designated global instance
parent
371d0a05
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Sources/VLCAppDelegate.m
View file @
ffc3b9ab
...
...
@@ -31,6 +31,7 @@
#import "VLCAlertView.h"
#import <BoxSDK/BoxSDK.h>
#import "VLCNotificationRelay.h"
#import "VLCPlaybackController.h"
#define HAVE_FABRIC 0
...
...
@@ -541,20 +542,23 @@
{
if
(
!
_movieViewController
)
_movieViewController
=
[[
VLCMovieViewController
alloc
]
initWithNibName
:
nil
bundle
:
nil
];
else
[
_movieViewController
unanimatedPlaybackStop
];
VLCPlaybackController
*
vpc
=
[
VLCPlaybackController
sharedInstance
];
if
([
mediaObject
isKindOfClass
:[
MLFile
class
]])
_movieViewController
.
fileFromMediaLibrary
=
(
MLFile
*
)
mediaObject
;
vpc
.
fileFromMediaLibrary
=
(
MLFile
*
)
mediaObject
;
else
if
([
mediaObject
isKindOfClass
:[
MLAlbumTrack
class
]])
_movieViewController
.
fileFromMediaLibrary
=
[(
MLAlbumTrack
*
)
mediaObject
files
].
anyObject
;
vpc
.
fileFromMediaLibrary
=
[(
MLAlbumTrack
*
)
mediaObject
files
].
anyObject
;
else
if
([
mediaObject
isKindOfClass
:[
MLShowEpisode
class
]])
_movieViewController
.
fileFromMediaLibrary
=
[(
MLShowEpisode
*
)
mediaObject
files
].
anyObject
;
[(
MLFile
*
)
_movieViewController
.
fileFromMediaLibrary
setUnread
:
@
(
NO
)];
vpc
.
fileFromMediaLibrary
=
[(
MLShowEpisode
*
)
mediaObject
files
].
anyObject
;
[(
MLFile
*
)
vpc
.
fileFromMediaLibrary
setUnread
:
@
(
NO
)];
vpc
.
delegate
=
_movieViewController
;
UINavigationController
*
navCon
=
[[
VLCPlaybackNavigationController
alloc
]
initWithRootViewController
:
_movieViewController
];
navCon
.
modalPresentationStyle
=
UIModalPresentationFullScreen
;
[
self
.
window
.
rootViewController
presentViewController
:
navCon
animated
:
YES
completion
:
nil
];
[
vpc
startPlayback
];
}
-
(
void
)
openMovieFromURL
:(
NSURL
*
)
url
...
...
@@ -564,13 +568,18 @@
if
(
!
_movieViewController
)
_movieViewController
=
[[
VLCMovieViewController
alloc
]
initWithNibName
:
nil
bundle
:
nil
];
_movieViewController
.
url
=
url
;
_movieViewController
.
successCallback
=
successCallback
;
_movieViewController
.
errorCallback
=
errorCallback
;
VLCPlaybackController
*
vpc
=
[
VLCPlaybackController
sharedInstance
];
vpc
.
url
=
url
;
vpc
.
successCallback
=
successCallback
;
vpc
.
errorCallback
=
errorCallback
;
vpc
.
delegate
=
_movieViewController
;
UINavigationController
*
navCon
=
[[
VLCPlaybackNavigationController
alloc
]
initWithRootViewController
:
_movieViewController
];
navCon
.
modalPresentationStyle
=
UIModalPresentationFullScreen
;
[
self
.
window
.
rootViewController
presentViewController
:
navCon
animated
:
YES
completion
:
nil
];
[
vpc
startPlayback
];
}
-
(
void
)
openMovieFromURL
:(
NSURL
*
)
url
...
...
@@ -583,13 +592,18 @@
if
(
!
_movieViewController
)
_movieViewController
=
[[
VLCMovieViewController
alloc
]
initWithNibName
:
nil
bundle
:
nil
];
_movieViewController
.
mediaList
=
list
;
_movieViewController
.
itemInMediaListToBePlayedFirst
=
index
;
_movieViewController
.
pathToExternalSubtitlesFile
=
nil
;
VLCPlaybackController
*
vpc
=
[
VLCPlaybackController
sharedInstance
];
vpc
.
mediaList
=
list
;
vpc
.
itemInMediaListToBePlayedFirst
=
index
;
vpc
.
pathToExternalSubtitlesFile
=
nil
;
vpc
.
delegate
=
_movieViewController
;
UINavigationController
*
navCon
=
[[
VLCPlaybackNavigationController
alloc
]
initWithRootViewController
:
_movieViewController
];
navCon
.
modalPresentationStyle
=
UIModalPresentationFullScreen
;
[
self
.
window
.
rootViewController
presentViewController
:
navCon
animated
:
YES
completion
:
nil
];
[
vpc
startPlayback
];
}
-
(
void
)
openMovieWithExternalSubtitleFromURL
:(
NSURL
*
)
url
externalSubURL
:(
NSString
*
)
SubtitlePath
...
...
@@ -597,12 +611,17 @@
if
(
!
_movieViewController
)
_movieViewController
=
[[
VLCMovieViewController
alloc
]
initWithNibName
:
nil
bundle
:
nil
];
_movieViewController
.
url
=
url
;
_movieViewController
.
pathToExternalSubtitlesFile
=
SubtitlePath
;
VLCPlaybackController
*
vpc
=
[
VLCPlaybackController
sharedInstance
];
vpc
.
url
=
url
;
vpc
.
pathToExternalSubtitlesFile
=
SubtitlePath
;
vpc
.
delegate
=
_movieViewController
;
UINavigationController
*
navCon
=
[[
VLCPlaybackNavigationController
alloc
]
initWithRootViewController
:
_movieViewController
];
navCon
.
modalPresentationStyle
=
UIModalPresentationFullScreen
;
[
self
.
window
.
rootViewController
presentViewController
:
navCon
animated
:
YES
completion
:
nil
];
[
vpc
startPlayback
];
}
#pragma mark - watch struff
...
...
@@ -658,14 +677,14 @@
-
(
NSDictionary
*
)
nowPlayingResponseDict
{
NSMutableDictionary
*
response
=
[
NSMutableDictionary
new
];
NSMutableDictionary
*
nowPlayingInfo
=
[[
MPNowPlayingInfoCenter
defaultCenter
].
nowPlayingInfo
mutableCopy
];
NSNumber
*
playbackTime
=
[
_movieViewController
mediaPlayer
]
.
time
.
numberValue
;
NSNumber
*
playbackTime
=
[
VLCPlaybackController
sharedInstance
].
mediaPlayer
.
time
.
numberValue
;
if
(
playbackTime
)
{
nowPlayingInfo
[
MPNowPlayingInfoPropertyElapsedPlaybackTime
]
=
@
(
playbackTime
.
floatValue
/
1000
);
}
if
(
nowPlayingInfo
)
{
response
[
@"nowPlayingInfo"
]
=
nowPlayingInfo
;
}
MLFile
*
currentFile
=
_movieViewController
.
currentlyPlayingMediaFile
;
MLFile
*
currentFile
=
[
VLCPlaybackController
sharedInstance
]
.
currentlyPlayingMediaFile
;
NSString
*
URIString
=
currentFile
.
objectID
.
URIRepresentation
.
absoluteString
;
if
(
URIString
)
{
response
[
@"URIRepresentation"
]
=
URIString
;
...
...
Sources/VLCEqualizerView.h
View file @
ffc3b9ab
...
...
@@ -25,10 +25,18 @@
@end
@protocol
VLCEqualizerViewUIDelegate
<
NSObject
>
@optional
-
(
void
)
equalizerViewReceivedUserInput
;
@end
@interface
VLCEqualizerView
:
VLCFrostedGlasView
<
UITableViewDataSource
,
UITableViewDelegate
>
@property
(
nonatomic
,
strong
)
UITableView
*
tableView
;
@property
(
weak
)
id
<
VLCEqualizerViewDelegate
>
delegate
;
@property
(
weak
)
id
<
VLCEqualizerViewUIDelegate
>
UIdelegate
;
-
(
void
)
reloadData
;
...
...
Sources/VLCEqualizerView.m
View file @
ffc3b9ab
...
...
@@ -268,12 +268,16 @@
{
if
(
self
.
delegate
)
[
self
.
delegate
setAmplification
:[
sender
value
]
forBand
:(
unsigned
)[
sender
tag
]];
if
([
self
.
UIdelegate
respondsToSelector
:
@selector
(
equalizerViewReceivedUserInput
)])
[
self
.
UIdelegate
equalizerViewReceivedUserInput
];
}
-
(
IBAction
)
preampSliderChangedValue
:(
VLCSlider
*
)
sender
{
if
(
self
.
delegate
)
[
self
.
delegate
setPreAmplification
:
sender
.
value
];
if
([
self
.
UIdelegate
respondsToSelector
:
@selector
(
equalizerViewReceivedUserInput
)])
[
self
.
UIdelegate
equalizerViewReceivedUserInput
];
}
-
(
void
)
reloadData
...
...
Sources/VLCMovieViewController.h
View file @
ffc3b9ab
...
...
@@ -13,13 +13,14 @@
#import <MediaPlayer/MediaPlayer.h>
#import "VLCFrostedGlasView.h"
#import "VLCPlaybackController.h"
@class
OBSlider
;
@class
VLCStatusLabel
;
@class
VLCHorizontalSwipeGestureRecognizer
;
@class
VLCVerticalSwipeGestureRecognizer
;
@interface
VLCMovieViewController
:
UIViewController
<
VLCMediaPlayerDelegate
,
UIActionSheet
Delegate
>
@interface
VLCMovieViewController
:
UIViewController
<
UIActionSheetDelegate
,
VLCPlaybackController
Delegate
>
@property
(
nonatomic
,
strong
)
IBOutlet
UIView
*
movieView
;
@property
(
nonatomic
,
strong
)
IBOutlet
UIBarButtonItem
*
backButton
;
...
...
@@ -84,20 +85,7 @@
@property
(
nonatomic
,
strong
)
IBOutlet
UILabel
*
trackNameLabel
;
@property
(
nonatomic
,
strong
)
IBOutlet
UIImageView
*
artworkImageView
;
@property
(
nonatomic
,
strong
)
MLFile
*
fileFromMediaLibrary
;
@property
(
nonatomic
,
strong
)
NSURL
*
url
;
@property
(
nonatomic
,
strong
)
NSURL
*
successCallback
;
@property
(
nonatomic
,
strong
)
NSURL
*
errorCallback
;
@property
(
nonatomic
,
strong
)
NSString
*
pathToExternalSubtitlesFile
;
@property
(
nonatomic
,
retain
)
VLCMediaList
*
mediaList
;
@property
(
nonatomic
,
strong
)
VLCMediaPlayer
*
mediaPlayer
;
@property
(
nonatomic
,
readwrite
)
int
itemInMediaListToBePlayedFirst
;
/* returns nil if currenlty plaing item is not a MLFile, e.g. a url */
@property
(
nonatomic
,
strong
,
readonly
)
MLFile
*
currentlyPlayingMediaFile
;
-
(
IBAction
)
closePlayback
:(
id
)
sender
;
-
(
void
)
unanimatedPlaybackStop
;
-
(
IBAction
)
positionSliderAction
:(
id
)
sender
;
-
(
IBAction
)
positionSliderTouchDown
:(
id
)
sender
;
...
...
Sources/VLCMovieViewController.m
View file @
ffc3b9ab
This diff is collapsed.
Click to expand it.
Sources/VLCPlaybackController.h
0 → 100644
View file @
ffc3b9ab
/*****************************************************************************
* VLCPlaybackController.h
* VLC for iOS
*****************************************************************************
* Copyright (c) 2013-2015 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
* Tobias Conradi <videolan # tobias-conradi.de>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import "VLCEqualizerView.h"
@class
VLCPlaybackController
;
@protocol
VLCPlaybackControllerDelegate
<
NSObject
>
-
(
void
)
playbackPositionUpdated
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
playbackRateUpdated
:(
float
)
rate
forPlaybackController
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
mediaPlayerStateChanged
:(
VLCMediaPlayerState
)
currentState
isPlaying
:(
BOOL
)
isPlaying
currentMediaHasTrackToChooseFrom
:(
BOOL
)
currentMediaHasTrackToChooseFrom
currentMediaHasChapters
:(
BOOL
)
currentMediaHasChapters
forPlaybackController
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
prepareForMediaPlayback
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
presentingViewControllerShouldBeClosed
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
presentingViewControllerShouldBeClosedAfterADelay
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
showStatusMessage
:(
NSString
*
)
statusMessage
forPlaybackController
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
audioOnlyPlaybackWasDetected
:(
BOOL
)
audioOnly
forPlaybackController
:(
VLCPlaybackController
*
)
controller
;
-
(
void
)
displayMetadataForPlaybackController
:(
VLCPlaybackController
*
)
controller
title
:(
NSString
*
)
title
artwork
:(
UIImage
*
)
artwork
artist
:(
NSString
*
)
artist
album
:(
NSString
*
)
album
audioOnly
:(
BOOL
)
audioOnly
;
@end
@interface
VLCPlaybackController
:
NSObject
<
VLCEqualizerViewDelegate
>
@property
(
nonatomic
,
readonly
)
VLCMediaListPlayer
*
listPlayer
;
@property
(
nonatomic
,
readonly
)
VLCMediaPlayer
*
mediaPlayer
;
@property
(
nonatomic
,
strong
)
UIView
*
videoOutputView
;
@property
(
nonatomic
,
strong
)
MLFile
*
fileFromMediaLibrary
;
@property
(
nonatomic
,
strong
)
NSURL
*
url
;
@property
(
nonatomic
,
strong
)
NSURL
*
successCallback
;
@property
(
nonatomic
,
strong
)
NSURL
*
errorCallback
;
@property
(
nonatomic
,
strong
)
NSString
*
pathToExternalSubtitlesFile
;
@property
(
nonatomic
,
retain
)
VLCMediaList
*
mediaList
;
@property
(
nonatomic
,
readwrite
)
int
itemInMediaListToBePlayedFirst
;
/* returns nil if currenlty plaing item is not a MLFile, e.g. a url */
@property
(
nonatomic
,
strong
,
readonly
)
MLFile
*
currentlyPlayingMediaFile
;
@property
(
nonatomic
,
weak
)
id
<
VLCPlaybackControllerDelegate
>
delegate
;
@property
(
nonatomic
,
readonly
)
VLCMediaPlayerState
mediaPlayerState
;
@property
(
nonatomic
,
readonly
)
NSInteger
mediaDuration
;
@property
(
nonatomic
,
readonly
)
BOOL
isPlaying
;
@property
(
nonatomic
,
readwrite
)
VLCRepeatMode
repeatMode
;
@property
(
nonatomic
,
readwrite
)
float
playbackRate
;
@property
(
nonatomic
,
readonly
)
BOOL
currentMediaHasChapters
;
@property
(
nonatomic
,
readonly
)
BOOL
currentMediaHasTrackToChooseFrom
;
+
(
VLCPlaybackController
*
)
sharedInstance
;
-
(
void
)
startPlayback
;
-
(
void
)
stopPlayback
;
-
(
void
)
playPause
;
-
(
void
)
forward
;
-
(
void
)
backward
;
-
(
void
)
switchAspectRatio
;
-
(
void
)
recoverDisplayedMetadata
;
@end
Sources/VLCPlaybackController.m
0 → 100644
View file @
ffc3b9ab
/*****************************************************************************
* VLCPlaybackController.m
* VLC for iOS
*****************************************************************************
* Copyright (c) 2013-2015 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
* Carola Nitz <caro # videolan.org>
* Gleb Pinigin <gpinigin # gmail.com>
* Pierre Sagaspe <pierre.sagaspe # me.com>
* Tobias Conradi <videolan # tobias-conradi.de>
* Sylver Bruneau <sylver.bruneau # gmail dot com>
* Winston Weinert <winston # ml1 dot net>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import "VLCPlaybackController.h"
#import <CommonCrypto/CommonDigest.h>
#import "UIDevice+VLC.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import "VLCThumbnailsCache.h"
#import <WatchKit/WatchKit.h>
@interface
VLCPlaybackController
()
<
AVAudioSessionDelegate
,
VLCMediaPlayerDelegate
,
VLCMediaDelegate
>
{
BOOL
_playerIsSetup
;
BOOL
_playbackFailed
;
BOOL
_shouldResumePlaying
;
NSArray
*
_aspectRatios
;
NSUInteger
_currentAspectRatioMask
;
float
_currentPlaybackRate
;
UIView
*
_videoOutputViewWrapper
;
UIView
*
_actualVideoOutputView
;
/* cached stuff for the VC */
NSString
*
_title
;
UIImage
*
_artworkImage
;
NSString
*
_artist
;
NSString
*
_albumName
;
BOOL
_mediaIsAudioOnly
;
}
@end
@implementation
VLCPlaybackController
#pragma mark instance management
+
(
VLCPlaybackController
*
)
sharedInstance
{
static
VLCPlaybackController
*
sharedInstance
=
nil
;
static
dispatch_once_t
pred
;
dispatch_once
(
&
pred
,
^
{
sharedInstance
=
[
self
new
];
});
return
sharedInstance
;
}
-
(
void
)
dealloc
{
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
];
}
#pragma mark - playback management
-
(
BOOL
)
_blobCheck
{
NSArray
*
searchPaths
=
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
);
NSString
*
directoryPath
=
searchPaths
[
0
];
if
(
!
[[
NSFileManager
defaultManager
]
fileExistsAtPath
:[
directoryPath
stringByAppendingPathComponent
:
@"blob.bin"
]])
return
NO
;
NSData
*
data
=
[
NSData
dataWithContentsOfFile
:[
directoryPath
stringByAppendingPathComponent
:
@"blob.bin"
]];
uint8_t
digest
[
CC_SHA1_DIGEST_LENGTH
];
CC_SHA1
(
data
.
bytes
,
(
unsigned
int
)
data
.
length
,
digest
);
NSMutableString
*
hash
=
[
NSMutableString
stringWithCapacity
:
CC_SHA1_DIGEST_LENGTH
*
2
];
for
(
unsigned
int
u
=
0
;
u
<
CC_SHA1_DIGEST_LENGTH
;
u
++
)
[
hash
appendFormat
:
@"%02x"
,
digest
[
u
]];
if
([
hash
isEqualToString
:
kBlobHash
])
return
YES
;
else
return
NO
;
}
-
(
BOOL
)
_isMediaSuitableForDevice
{
if
(
!
self
.
fileFromMediaLibrary
)
return
YES
;
NSUInteger
totalNumberOfPixels
=
[[[
self
.
fileFromMediaLibrary
videoTrack
]
valueForKey
:
@"width"
]
doubleValue
]
*
[[[
self
.
fileFromMediaLibrary
videoTrack
]
valueForKey
:
@"height"
]
doubleValue
];
NSInteger
speedCategory
=
[[
UIDevice
currentDevice
]
speedCategory
];
if
(
speedCategory
==
1
)
{
// iPhone 3GS, iPhone 4, first gen. iPad, 3rd and 4th generation iPod touch
return
(
totalNumberOfPixels
<
600000
);
// between 480p and 720p
}
else
if
(
speedCategory
==
2
)
{
// iPhone 4S, iPad 2 and 3, iPod 4 and 5
return
(
totalNumberOfPixels
<
922000
);
// 720p
}
else
if
(
speedCategory
==
3
)
{
// iPhone 5, iPad 4
return
(
totalNumberOfPixels
<
2074000
);
// 1080p
}
else
if
(
speedCategory
==
4
)
{
// iPhone 6, 2014 iPads
return
(
totalNumberOfPixels
<
8850000
);
// 4K
}
return
YES
;
}
-
(
void
)
startPlayback
{
if
(
_playerIsSetup
)
return
;
[[
AVAudioSession
sharedInstance
]
setDelegate
:
self
];
NSNotificationCenter
*
defaultCenter
=
[
NSNotificationCenter
defaultCenter
];
[
defaultCenter
addObserver
:
self
selector
:
@selector
(
audioSessionRouteChange
:
)
name:
AVAudioSessionRouteChangeNotification
object
:
nil
];
[
defaultCenter
addObserver
:
self
selector
:
@selector
(
applicationWillResignActive
:
)
name:
UIApplicationWillResignActiveNotification
object
:
nil
];
[
defaultCenter
addObserver
:
self
selector
:
@selector
(
applicationDidBecomeActive
:
)
name:
UIApplicationDidBecomeActiveNotification
object
:
nil
];
[
defaultCenter
addObserver
:
self
selector
:
@selector
(
applicationDidEnterBackground
:
)
name:
UIApplicationDidEnterBackgroundNotification
object
:
nil
];
NSUserDefaults
*
defaults
=
[
NSUserDefaults
standardUserDefaults
];
_aspectRatios
=
@[
@"DEFAULT"
,
@"FILL_TO_SCREEN"
,
@"4:3"
,
@"16:9"
,
@"16:10"
,
@"2.21:1"
];
if
(
!
self
.
fileFromMediaLibrary
&&
!
self
.
url
&&
!
self
.
mediaList
)
{
[
self
stopPlayback
];
return
;
}
if
(
self
.
pathToExternalSubtitlesFile
)
_listPlayer
=
[[
VLCMediaListPlayer
alloc
]
initWithOptions
:@[[
NSString
stringWithFormat
:
@"--%@=%@"
,
kVLCSettingSubtitlesFilePath
,
self
.
pathToExternalSubtitlesFile
]]];
else
_listPlayer
=
[[
VLCMediaListPlayer
alloc
]
init
];
/* video decoding permanently fails if we don't provide a UIView to draw into on init
* hence we provide one which is not attached to any view controller for off-screen drawing
* and disable video decoding once playback started */
_actualVideoOutputView
=
[[
UIView
alloc
]
initWithFrame
:[
UIScreen
mainScreen
].
bounds
];
_actualVideoOutputView
.
autoresizingMask
=
UIViewAutoresizingFlexibleWidth
|
UIViewAutoresizingFlexibleHeight
;
_actualVideoOutputView
.
autoresizesSubviews
=
YES
;
_mediaPlayer
=
_listPlayer
.
mediaPlayer
;
[
_mediaPlayer
setDelegate
:
self
];
[
_mediaPlayer
setDrawable
:
_actualVideoOutputView
];
if
([[
defaults
objectForKey
:
kVLCSettingPlaybackSpeedDefaultValue
]
floatValue
]
!=
0
)
[
_mediaPlayer
setRate
:
[[
defaults
objectForKey
:
kVLCSettingPlaybackSpeedDefaultValue
]
floatValue
]];
if
([[
defaults
objectForKey
:
kVLCSettingDeinterlace
]
intValue
]
!=
0
)
[
_mediaPlayer
setDeinterlaceFilter
:
@"blend"
];
else
[
_mediaPlayer
setDeinterlaceFilter
:
nil
];
if
(
self
.
pathToExternalSubtitlesFile
)
[
_mediaPlayer
openVideoSubTitlesFromFile
:
self
.
pathToExternalSubtitlesFile
];
VLCMedia
*
media
;
if
(
self
.
fileFromMediaLibrary
)
{
MLFile
*
item
=
self
.
fileFromMediaLibrary
;
media
=
[
VLCMedia
mediaWithURL
:[
NSURL
URLWithString
:
item
.
url
]];
media
.
delegate
=
self
;
}
else
if
(
self
.
mediaList
)
{
media
=
[
self
.
mediaList
mediaAtIndex
:
self
.
itemInMediaListToBePlayedFirst
];
media
.
delegate
=
self
;
}
else
{
media
=
[
VLCMedia
mediaWithURL
:
self
.
url
];
media
.
delegate
=
self
;
[
media
parse
];
}
NSMutableDictionary
*
mediaDictionary
=
[[
NSMutableDictionary
alloc
]
init
];
[
mediaDictionary
setObject
:[
defaults
objectForKey
:
kVLCSettingNetworkCaching
]
forKey
:
kVLCSettingNetworkCaching
];
[
mediaDictionary
setObject
:[[
defaults
objectForKey
:
kVLCSettingStretchAudio
]
boolValue
]
?
kVLCSettingStretchAudioOnValue
:
kVLCSettingStretchAudioOffValue
forKey
:
kVLCSettingStretchAudio
];
[
mediaDictionary
setObject
:[
defaults
objectForKey
:
kVLCSettingTextEncoding
]
forKey
:
kVLCSettingTextEncoding
];
[
mediaDictionary
setObject
:[
defaults
objectForKey
:
kVLCSettingSkipLoopFilter
]
forKey
:
kVLCSettingSkipLoopFilter
];
#if 0
[NSTimeZone resetSystemTimeZone];
NSString *tzName = [[NSTimeZone systemTimeZone] name];
NSArray *tzNames = @[@"America/Adak", @"America/Anchorage", @"America/Boise", @"America/Chicago", @"America/Denver", @"America/Detroit", @"America/Indiana/Indianapolis", @"America/Indiana/Knox", @"America/Indiana/Marengo", @"America/Indiana/Petersburg", @"America/Indiana/Tell_City", @"America/Indiana/Vevay", @"America/Indiana/Vincennes", @"America/Indiana/Winamac", @"America/Juneau", @"America/Kentucky/Louisville", @"America/Kentucky/Monticello", @"America/Los_Angeles", @"America/Menominee", @"America/Metlakatla", @"America/New_York", @"America/Nome", @"America/North_Dakota/Beulah", @"America/North_Dakota/Center", @"America/North_Dakota/New_Salem", @"America/Phoenix", @"America/Puerto_Rico", @"America/Shiprock", @"America/Sitka", @"America/St_Thomas", @"America/Thule", @"America/Yakutat", @"Pacific/Guam", @"Pacific/Honolulu", @"Pacific/Johnston", @"Pacific/Kwajalein", @"Pacific/Midway", @"Pacific/Pago_Pago", @"Pacific/Saipan", @"Pacific/Wake"];
if ([tzNames containsObject:tzName] || [[tzName stringByDeletingLastPathComponent] isEqualToString:@"US"]) {
NSArray *tracksInfo = media.tracksInformation;
for (NSUInteger x = 0; x < tracksInfo.count; x++) {
if ([[tracksInfo[x] objectForKey:VLCMediaTracksInformationType] isEqualToString:VLCMediaTracksInformationTypeAudio])
{
NSInteger fourcc = [[tracksInfo[x] objectForKey:VLCMediaTracksInformationCodec] integerValue];
switch (fourcc) {
case 540161377:
case 1647457633:
case 858612577:
case 862151027:
case 862151013:
case 1684566644:
case 2126701:
{
if (![self _blobCheck]) {
[mediaDictionary setObject:[NSNull null] forKey:@"no-audio"];
APLog(@"audio playback disabled because an unsupported codec was found");
}
break;
}
default:
break;
}
}
}
}
#endif
if
(
self
.
mediaList
)
{
VLCMediaList
*
list
=
self
.
mediaList
;
NSUInteger
count
=
list
.
count
;
for
(
NSUInteger
x
=
0
;
x
<
count
;
x
++
)
[[
list
mediaAtIndex
:
x
]
addOptions
:
mediaDictionary
];
[
_listPlayer
setMediaList
:
self
.
mediaList
];
}
else
{
[
media
addOptions
:
mediaDictionary
];
[
_listPlayer
setRootMedia
:
media
];
}
[
_listPlayer
setRepeatMode
:
VLCDoNotRepeat
];
if
(
!
[
self
_isMediaSuitableForDevice
])
{
UIAlertView
*
alert
=
[[
UIAlertView
alloc
]
initWithTitle
:
NSLocalizedString
(
@"DEVICE_TOOSLOW_TITLE"
,
nil
)
message
:[
NSString
stringWithFormat
:
NSLocalizedString
(
@"DEVICE_TOOSLOW"
,
nil
),
[[
UIDevice
currentDevice
]
model
],
self
.
fileFromMediaLibrary
.
title
]
delegate
:
self
cancelButtonTitle
:
NSLocalizedString
(
@"BUTTON_CANCEL"
,
nil
)
otherButtonTitles
:
NSLocalizedString
(
@"BUTTON_OPEN"
,
nil
),
nil
];
[
alert
show
];
}
else
[
self
_playNewMedia
];
}
-
(
void
)
_playNewMedia
{
NSNumber
*
playbackPositionInTime
=
@
(
0
);
CGFloat
lastPosition
=
.
0
;
NSInteger
duration
=
0
;
MLFile
*
matchedFile
;
// Set last selected equalizer profile
unsigned
int
profile
=
(
unsigned
int
)[[[
NSUserDefaults
standardUserDefaults
]
objectForKey
:
kVLCSettingEqualizerProfile
]
integerValue
];
[
_mediaPlayer
resetEqualizerFromProfile
:
profile
];
[
_mediaPlayer
setPreAmplification
:[
_mediaPlayer
preAmplification
]];
if
(
self
.
fileFromMediaLibrary
)
matchedFile
=
self
.
fileFromMediaLibrary
;
else
if
(
self
.
mediaList
)
{
/* TODO: move this code to MLKit */
NSString
*
path
=
[[[
self
.
mediaList
mediaAtIndex
:
self
.
itemInMediaListToBePlayedFirst
]
url
]
absoluteString
];
NSString
*
componentString
=
@""
;
NSArray
*
pathComponents
=
[
path
componentsSeparatedByString
:
@"/"
];
NSUInteger
componentCount
=
pathComponents
.
count
;
if
([
pathComponents
[
componentCount
-
2
]
isEqualToString
:
@"Documents"
])
componentString
=
[
path
lastPathComponent
];
else
{
NSUInteger
firstElement
=
[
pathComponents
indexOfObject
:
@"Documents"
]
+
1
;
for
(
NSUInteger
x
=
0
;
x
<
componentCount
-
firstElement
;
x
++
)
{
if
(
x
==
0
)
componentString
=
[
componentString
stringByAppendingFormat
:
@"%@"
,
pathComponents
[
firstElement
+
x
]];
else
componentString
=
[
componentString
stringByAppendingFormat
:
@"/%@"
,
pathComponents
[
firstElement
+
x
]];
}
}
NSFetchRequest
*
request
=
[[
NSFetchRequest
alloc
]
init
];
NSManagedObjectContext
*
moc
=
[[
MLMediaLibrary
sharedMediaLibrary
]
managedObjectContext
];
if
(
moc
)
{
NSEntityDescription
*
entity
=
[
NSEntityDescription
entityForName
:
@"File"
inManagedObjectContext
:
moc
];
[
request
setEntity
:
entity
];
[
request
setPredicate
:[
NSPredicate
predicateWithFormat
:
@"url CONTAINS %@"
,
componentString
]];
NSSortDescriptor
*
descriptor
=
[[
NSSortDescriptor
alloc
]
initWithKey
:
@"title"
ascending
:
YES
selector
:
@selector
(
localizedCaseInsensitiveCompare
:
)];
[
request
setSortDescriptors
:@[
descriptor
]];
NSArray
*
matches
=
[
moc
executeFetchRequest
:
request
error
:
nil
];
if
(
matches
.
count
>
0
)
matchedFile
=
matches
[
0
];
}
}
if
(
matchedFile
.
lastPosition
)
lastPosition
=
matchedFile
.
lastPosition
.
floatValue
;
duration
=
matchedFile
.
duration
.
intValue
;
if
(
lastPosition
<
.
95
)
{
if
(
duration
!=
0
)
playbackPositionInTime
=
@
(
lastPosition
*
(
duration
/
1000
.));
}
if
(
playbackPositionInTime
.
intValue
>
0
&&
(
duration
*
lastPosition
-
duration
)
<
-
60000
)
{
[
_mediaPlayer
.
media
addOptions
:@{
@"start-time"
:
playbackPositionInTime
}];
APLog
(
@"set starttime to %i"
,
playbackPositionInTime
.
intValue
);
}
[
_mediaPlayer
addObserver
:
self
forKeyPath
:
@"time"
options
:
0
context
:
nil
];
[
_mediaPlayer
addObserver
:
self
forKeyPath
:
@"remainingTime"
options
:
0
context
:
nil
];
if
(
self
.
mediaList
)
[
_listPlayer
playItemAtIndex
:
self
.
itemInMediaListToBePlayedFirst
];
else
[
_listPlayer
playMedia
:
_listPlayer
.
rootMedia
];
if
(
matchedFile
)
{
if
(
matchedFile
.
lastAudioTrack
.
intValue
>
0
)
_mediaPlayer
.
currentAudioTrackIndex
=
matchedFile
.
lastAudioTrack
.
intValue
;
if
(
matchedFile
.
lastSubtitleTrack
.
intValue
>
0
)
_mediaPlayer
.
currentVideoSubTitleIndex
=
matchedFile
.
lastSubtitleTrack
.
intValue
;
}
if
([
self
.
delegate
respondsToSelector
:
@selector
(
prepareForMediaPlayback
:)])
[
self
.
delegate
prepareForMediaPlayback
:
self
];