Пример простого видеоплеера

| Комментариев: 8 | Нет трекбэков

Задача: Создать самый простой видеоплеер, выводящий заданный ролик.

Посидел и поковырял. Что из этого вышло.

Для начала нам понадобится видеофайл, который мы будем проигрывать. Вот пример конвертирования с использованием ffmpeg, libx264 и libfaac.

ffmpeg -i INPUT.AVI -acodec libfaac -ac 2 -ar 44100 -ab 128k -s 320x240\
-vcodec libx264 -b 300k -flags +loop -cmp +chroma -partitions\
+parti4x4+partp8x8+partb8x8 -me umh -subq 5 -trellis 1 -refs 1 -coder\
0 -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71\
-bt 300k -maxrate 300k -bufsize 300k -rc_eq 'blurCplx^(1-qComp)'\
-qcomp 0.6 -qmin 15 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 OUTPUT.MP4

где INPUT.AVI (может быть любой) исходный файл и OUTPUT.MP4 - сконвертированный файл.

Для начала нам надо добавить в makefile фреймворк MoviePlayerUI.

Makefile

PRODUCT_NAME = SimpleMoviePlayer
BUNDLE_NAME = $(PRODUCT_NAME).app
SOURCES = $(wildcard *.m)
INFOPLIST_FILE = Info.plist
PNGS = $(wildcard *.png)

CC = arm-apple-darwin-gcc
CXX = arm-apple-darwin-g++

CFLAGS = -Wall -pipe -O3

LD = ${CC}
LDFLAGS = -Wl,-syslibroot,/usr/local/share/iphone-filesystem \
          -I/usr/local/arm-apple-darwin/include \
          -lobjc \
          -larmfp \
          -framework CoreFoundation \
          -framework Foundation \
          -framework CoreGraphics \
          -framework GraphicsServices \
          -framework UIKit \
          -framework Celestial \
          -framework MoviePlayerUI

EXECUTABLE_NAME = $(PRODUCT_NAME)

OBJECTS = \
    $(patsubst %.c,%.o,$(filter %.c,$(SOURCES))) \
    $(patsubst %.cc,%.o,$(filter %.cc,$(SOURCES))) \
    $(patsubst %.cpp,%.o,$(filter %.cpp,$(SOURCES))) \
    $(patsubst %.m,%.o,$(filter %.m,$(SOURCES))) \
    $(patsubst %.mm,%.o,$(filter %.mm,$(SOURCES)))

all: $(PRODUCT_NAME) bundle

$(PRODUCT_NAME): $(OBJECTS)
    $(LD) $(LDFLAGS) -o $(PRODUCT_NAME) $(OBJECTS)

%.o: %.m
    $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

clean:
    rm -f *.o $(EXECUTABLE_NAME)
    rm -rf $(BUNDLE_NAME)
    rm -f *~

bundle:
    mkdir -p $(BUNDLE_NAME)
    cp $(INFOPLIST_FILE) $(BUNDLE_NAME)/
    cp $(PNGS) $(BUNDLE_NAME)/
    cp $(EXECUTABLE_NAME) $(BUNDLE_NAME)/
    cp PkgInfo $(BUNDLE_NAME)/

main.m

#import <UIKit/UIKit.h>
#import "SimpleMoviePlayerApp.h"

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int ret = UIApplicationMain(argc, argv, [SimpleMoviePlayerApp class]);
    [pool release];
    return ret;
}

Ниже я использую UIEventObservableWindow вместо UIWindow для правильной обработки событий от плеера.

SimpleMoviePlayer.h

#import <UIKit/UIKit.h>
#import <GraphicsServices/GraphicsServices.h>
#import <MoviePlayerUI/UIEventObservableWindow.h>
#import <MoviePlayerUI/UIMovieView.h>
#import <MoviePlayerUI/UIMoviePlayerController.h>

@interface SimpleMoviePlayerApp : UIApplication
{
    UIEventObservableWindow *mainWindow;
    UIMoviePlayerController *playerController;
}

@end

Функция moviePlayerDidFinishPlayback, описанная ниже, вызывается при завершении проигрывания видеофайла (Нажатие на кнопку “Done” или конец видеофайла).

SimpleMoviePlayer.m

#import "SimpleMoviePlayerApp.h"

@implementation SimpleMoviePlayerApp

- (void)applicationDidFinishLaunching:(GSEventRef)event;
{

    struct CGRect mainFrame = CGRectMake(0,0,320,480);

    mainWindow = [[UIEventObservableWindow alloc] initWithContentRect:mainFrame];

    playerController = [[UIMoviePlayerController alloc] 
                initWithPlayerSize:[UIHardware mainScreenSize] isFullScreen:YES];
    [[playerController playerView] setCanShowControlsOverlay:YES];
    [playerController setControlsOverlayVisible:YES disableAutohide:NO animate: YES];
    [playerController setAutoPlayWhenLikelyToKeepUp:YES];
    [playerController setDelegate:self];
    [playerController prepareAndSetupUI];
    [[playerController movieView] setMovieWithPath:@"http://192.168.0.2/video.m4v"];

    [mainWindow setContentView:[playerController playerView]];
    [mainWindow orderFront:self];
}

- (void)moviePlayerDidFinishPlayback: (UIMoviePlayerController *)player 
                                          userExited: (BOOL)userExited
{
    NSLog(@"player normal exit");
    [self terminateWithSuccess];
}

- (void)applicationWillTerminate;
{
    NSLog(@"app normal exit");
    [playerController release];
    [mainWindow release];
}
@end

Info.plist

<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>Russian</string>
    <key>CFBundleExecutable</key>
    <string>SimpleMoviePlayer</string>
    <key>CFBundleIdentifier</key>
    <string>com.wndev.simplemovieplayer</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>0.1</string></dict>
</plist>

Скачать исходный код и бинарник можно по ссылке simplemovieplayer.zip

Ждем ваши вопросы и предложения в комментариях.

Нет трекбэков

URL для трекбэков: http://weho.ru/cgi-bin/mt/mt-tb.cgi/68

Комментариев: 8

почему при загрузке видео выводится надпись "Загружаю фильм..." хотя этого нет в исходниках и у меня стоит Английский интерфейс?

Вы не могли бы более подробно описать вопрос? Не совсем понятно, где это происходит. Если можно - кусок кода, где происходит запуск плеера.

я просто скомпилил ваш исходник без изменений, вот картинка - http://iphone.wheepy.ru/smp.jpg

еще вопрос, попытался добавить AlertSheet в плеер по окончании ролика:

добавил в .h:
- (void)showAlertSheet;

ну и есстественно хидеры.

добавил в .m:
- (void)moviePlayerDidFinishPlayback: (UIMoviePlayerController *)player userExited: (BOOL)userExited
{
[self showAlertSheet]
}

- (void)showAlertSheet;
{
UIAlertSheet *alert = [[UIAlertSheet alloc] init];
[alert setTitle:@"Chooose file"];
[alert setBodyText:@"Hey!"];
[alert addButtonWithTitle:@"ok"];
[alert setDelegate:self];
[alert setContext:self];
[alert popupAlertAnimated:YES];
}

старую DidFinishPlayback убрал.

Не компилируется, выдает ошибку в DidFinishPlayback

Насчёт языка приложения: возможно, у Вас в файле Info.plist параметр CFBundleDevelopmentRegion выставлен в Russian. Вследствие этого надпись "Загружаю фильм..." выводится именно на русском. Попробуйте в файле переписать Russian на English. Если не поможет - сообщите, будем думать дальше.

hobbut, narmo

спасибо, и то и то помогло

Пожалуйста, всегда рады помочь.

Комментировать

Об этой записи

Сообщение опубликовано 23.04.2008 23:24. Автор — hobbut.

Предыдущая запись — Локализация приложений iPhone

Следующая запись — Cydia vs Installer.app

Смотрите новые записи на главной странице или загляните в архив, где есть ссылки на все сообщения.

Работает на Movable Type 5.01
Хороший хостинг