Reputation:
I'm initialising an MPMoviePlayerViewController
to a source .mp4 on a server which supports Range requests and all that, and in fact the code I am using works fine on an iPhone 4, iPhone 3GS and iPad running iOS 4.
I have an iPhone 3G running iOS 4. The movie player class on this device begins to stream, and then immediately finishes playback. It doesn't error, though, it simply finishes playback as evidenced by printing the MPMoviePlaybackDidFinishNotification
; it comes back with MPMoviePlayerPlaybackDidFinishReasonUserInfoKey = 0
, which I take to mean MPMovieFinishReasonPlaybackEnded
considering that's the first value of the enum. I've even tried setting a playback hint, MPMovieSourceType = MPMovieSourceTypeStreaming
.
The issue is that if I navigate to the very same URL in Safari on the iPhone 3G, it streams and plays the movie without error. I'm totally stumped, and Google has so far turned up nothing specific to the 3G. Possible solutions include creating a custom AVFoundation
implementation (not at all ideal) or using MPMoviePlayerController
on 3G devices. If someone has guidance on switching based on the model of iPhone, not the version of iOS running, that would be great.
Using CFNotificationObserver callback registration, I have received the following notifications of interest:
Name: AVFileValidatorNotification_NotPlayable <-- likely the source of the issue
Info: Error = "Error
Domain=NSOSStatusErrorDomain
Code=-12621
\"This movie could not be played.\" "
Name: FailedToBecomeReadyForInspection
Info: Properties = ( InitialSamples );
Result = "-12621";
Name: AVController_ItemFailedToPlay
Info: "AVController_Error" = (the above Error object);
"AVController_Item" = "<MPAVItem: 0x1b65d0>";
Name: MPAvControllerPlaybackStateChangedNotification
// Got several of these, the playback state changed as follows: 0 -> 2 -> 7 -> 0
Upvotes: 1
Views: 4562
Reputation:
How's this for resolution: it "just works" now. What changed? I changed the Bundle ID of the app, I made a couple of interface tweaks elsewhere, but nothing from the actual presentation or setup of the movie player object changed. I haven't rebooted the phone; I did delete the app with the old Bundle ID though.
I'm not particularly happy that it randomly fixed itself, especially if reinstalling the app was all it took. It means that a couple of end users may encounter the same issue if the installation is "corrupted" in the same way mine may have been.
Upvotes: 1
Reputation: 43472
Debugging video playback is tricky. If you add a universal notification observer, you can see a lot more of what's happening behind the scenes:
CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), NULL, &someCallback, NULL, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
With someCallback()
:
void someCallBack(
CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo
);
Notice I've used CFNotificationCenter
here instead of NSNotificationCenter
. Some of the notifications that get passed around use pointers in their arguments that cannot be coerced to id
, so they cause crashes when a global observer is added via Cocoa. This isn't an issue at the Core Foundation level, where it is legal to use junk pointers for this purpose.
Edit: Based on the error you're getting--the video may be too high-quality for the decoder chip on the 3G (Safari may use a different decoding path that allows for more flexibility in its playback support.) Newer devices support higher-quality H.264 video, while older ones are limited in their formats. What's the resolution and H.264 profile of the video?
Also, if the video is installed onto the device directly, does it play?
Upvotes: 2