mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
Add media service implementation for iOS
This commit is contained in:
@@ -145,7 +145,12 @@ template("ios_app") {
|
||||
bin_gen_target_name = target_name + "_bin"
|
||||
|
||||
executable(bin_gen_target_name) {
|
||||
libs = [ "UIKit.framework", "QuartzCore.framework", "OpenGLES.framework" ]
|
||||
libs = [
|
||||
"UIKit.framework",
|
||||
"AVFoundation.framework",
|
||||
"QuartzCore.framework",
|
||||
"OpenGLES.framework"
|
||||
]
|
||||
deps = invoker.deps
|
||||
output_name = app_name
|
||||
}
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
import("//mojo/public/tools/bindings/mojom.gni")
|
||||
|
||||
group("media") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
":interfaces",
|
||||
]
|
||||
|
||||
if (is_android) {
|
||||
if (is_android || is_ios) {
|
||||
deps += [ ":media_lib" ]
|
||||
}
|
||||
}
|
||||
@@ -40,4 +38,20 @@ if (is_android) {
|
||||
":interfaces_java",
|
||||
]
|
||||
}
|
||||
} else if (is_ios) {
|
||||
source_set("media_lib") {
|
||||
sources = [
|
||||
"ios/media_player_impl.h",
|
||||
"ios/media_player_impl.mm",
|
||||
"ios/media_service_impl.h",
|
||||
"ios/media_service_impl.mm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":interfaces",
|
||||
"//base:base",
|
||||
"//mojo/common",
|
||||
"//mojo/public/cpp/application",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SKY_SERVICES_MEDIA_IOS_MEDIA_PLAYER_IMPL_H_
|
||||
#define SKY_SERVICES_MEDIA_IOS_MEDIA_PLAYER_IMPL_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "mojo/public/cpp/application/interface_factory.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "sky/services/media/media.mojom.h"
|
||||
|
||||
#if __OBJC__
|
||||
@class AudioClient;
|
||||
#else // __OBJC__
|
||||
class AudioClient;
|
||||
#endif // __OBJC__
|
||||
|
||||
namespace sky {
|
||||
namespace services {
|
||||
namespace media {
|
||||
|
||||
class MediaPlayerImpl : public ::media::MediaPlayer {
|
||||
public:
|
||||
explicit MediaPlayerImpl(
|
||||
mojo::InterfaceRequest<::media::MediaPlayer> request);
|
||||
~MediaPlayerImpl() override;
|
||||
|
||||
void Prepare(mojo::ScopedDataPipeConsumerHandle data_source,
|
||||
const ::media::MediaPlayer::PrepareCallback& callback) override;
|
||||
void Start() override;
|
||||
void Pause() override;
|
||||
void SeekTo(uint32_t msec) override;
|
||||
|
||||
private:
|
||||
mojo::StrongBinding<::media::MediaPlayer> binding_;
|
||||
AudioClient* audio_client_;
|
||||
|
||||
void reset();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MediaPlayerImpl);
|
||||
};
|
||||
|
||||
class MediaPlayerFactory : public mojo::InterfaceFactory<::media::MediaPlayer> {
|
||||
public:
|
||||
void Create(mojo::ApplicationConnection* connection,
|
||||
mojo::InterfaceRequest<::media::MediaPlayer> request) override;
|
||||
};
|
||||
|
||||
} // namespace media
|
||||
} // namespace services
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SERVICES_MEDIA_IOS_MEDIA_PLAYER_IMPL_H_
|
||||
@@ -0,0 +1,134 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "mojo/common/data_pipe_utils.h"
|
||||
#include "sky/services/media/ios/media_player_impl.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
@interface AudioClient : NSObject
|
||||
|
||||
- (instancetype)initWithPath:(NSString*)path;
|
||||
|
||||
- (BOOL)play;
|
||||
- (void)pause;
|
||||
- (BOOL)seekTo:(NSTimeInterval)interval;
|
||||
|
||||
+ (NSString*)temporaryFilePath;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AudioClient {
|
||||
AVAudioPlayer* _player;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPath:(NSString*)path {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
NSError* error = nil;
|
||||
_player =
|
||||
[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path]
|
||||
error:&error];
|
||||
|
||||
if (error != nil) {
|
||||
NSLog(@"Could not initialize audio client: %@",
|
||||
error.localizedDescription);
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)play {
|
||||
return [_player play];
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
[_player pause];
|
||||
}
|
||||
|
||||
- (BOOL)seekTo:(NSTimeInterval)interval {
|
||||
return [_player playAtTime:_player.deviceCurrentTime + interval];
|
||||
}
|
||||
|
||||
+ (NSString*)temporaryFilePath {
|
||||
char* path = reinterpret_cast<char*>(calloc(256, sizeof(char)));
|
||||
|
||||
snprintf(path, 256, "%smedia.XXXXXX", NSTemporaryDirectory().UTF8String);
|
||||
path = mktemp(path);
|
||||
|
||||
if (path == NULL) {
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSString* pathString = [NSString stringWithUTF8String:path];
|
||||
free(path);
|
||||
|
||||
return pathString;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_player release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace sky {
|
||||
namespace services {
|
||||
namespace media {
|
||||
|
||||
MediaPlayerImpl::MediaPlayerImpl(
|
||||
mojo::InterfaceRequest<::media::MediaPlayer> request)
|
||||
: binding_(this, request.Pass()), audio_client_(nullptr) {}
|
||||
|
||||
MediaPlayerImpl::~MediaPlayerImpl() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::Prepare(
|
||||
mojo::ScopedDataPipeConsumerHandle data_source,
|
||||
const ::media::MediaPlayer::PrepareCallback& callback) {
|
||||
reset();
|
||||
|
||||
NSString* filePath = [AudioClient temporaryFilePath];
|
||||
base::FilePath path(filePath.UTF8String);
|
||||
mojo::common::BlockingCopyToFile(data_source.Pass(), path);
|
||||
audio_client_ = [[AudioClient alloc] initWithPath:filePath];
|
||||
callback.Run(audio_client_ != nullptr);
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::Start() {
|
||||
[audio_client_ play];
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::Pause() {
|
||||
[audio_client_ pause];
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::SeekTo(uint32_t msec) {
|
||||
[audio_client_ seekTo:msec * 1e-3];
|
||||
}
|
||||
|
||||
void MediaPlayerImpl::reset() {
|
||||
[audio_client_ release];
|
||||
audio_client_ = nullptr;
|
||||
}
|
||||
|
||||
void MediaPlayerFactory::Create(
|
||||
mojo::ApplicationConnection* connection,
|
||||
mojo::InterfaceRequest<::media::MediaPlayer> request) {
|
||||
new MediaPlayerImpl(request.Pass());
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
} // namespace services
|
||||
} // namespace sky
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SKY_SERVICES_MEDIA_IOS_MEDIA_SERVICE_IMPL_H_
|
||||
#define SKY_SERVICES_MEDIA_IOS_MEDIA_SERVICE_IMPL_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "mojo/public/cpp/application/interface_factory.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "sky/services/media/media.mojom.h"
|
||||
#include "sky/services/media/ios/media_player_impl.h"
|
||||
|
||||
namespace sky {
|
||||
namespace services {
|
||||
namespace media {
|
||||
|
||||
class MediaServiceImpl : public ::media::MediaService {
|
||||
public:
|
||||
MediaServiceImpl(mojo::InterfaceRequest<::media::MediaService> request);
|
||||
~MediaServiceImpl() override;
|
||||
|
||||
void CreatePlayer(
|
||||
mojo::InterfaceRequest<::media::MediaPlayer> player) override;
|
||||
|
||||
private:
|
||||
mojo::StrongBinding<::media::MediaService> binding_;
|
||||
MediaPlayerFactory media_player_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MediaServiceImpl);
|
||||
};
|
||||
|
||||
class MediaServiceFactory
|
||||
: public mojo::InterfaceFactory<::media::MediaService> {
|
||||
public:
|
||||
void Create(mojo::ApplicationConnection* connection,
|
||||
mojo::InterfaceRequest<::media::MediaService> request) override;
|
||||
};
|
||||
|
||||
} // namespace media
|
||||
} // namespace services
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SERVICES_MEDIA_IOS_MEDIA_SERVICE_IMPL_H_
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sky/services/media/ios/media_service_impl.h"
|
||||
|
||||
namespace sky {
|
||||
namespace services {
|
||||
namespace media {
|
||||
|
||||
MediaServiceImpl::MediaServiceImpl(
|
||||
mojo::InterfaceRequest<::media::MediaService> request)
|
||||
: binding_(this, request.Pass()) {}
|
||||
|
||||
MediaServiceImpl::~MediaServiceImpl() {}
|
||||
|
||||
void MediaServiceImpl::CreatePlayer(
|
||||
mojo::InterfaceRequest<::media::MediaPlayer> player) {
|
||||
media_player_.Create(nullptr, player.Pass());
|
||||
}
|
||||
|
||||
void MediaServiceFactory::Create(
|
||||
mojo::ApplicationConnection* connection,
|
||||
mojo::InterfaceRequest<::media::MediaService> request) {
|
||||
new MediaServiceImpl(request.Pass());
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
} // namespace services
|
||||
} // namespace sky
|
||||
@@ -212,6 +212,7 @@ if (is_android) {
|
||||
":common",
|
||||
"//sky/services/ns_net",
|
||||
"//sky/services/keyboard",
|
||||
"//sky/services/media",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include "sky/services/keyboard/ios/keyboard_service_impl.h"
|
||||
#include "sky/services/media/ios/media_service_impl.h"
|
||||
#include "sky/services/media/ios/media_player_impl.h"
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
@@ -39,6 +41,14 @@ class PlatformServiceProvider : public mojo::ServiceProvider {
|
||||
keyboard_.Create(nullptr, mojo::MakeRequest<::keyboard::KeyboardService>(
|
||||
client_handle.Pass()));
|
||||
}
|
||||
if (service_name == ::media::MediaPlayer::Name_) {
|
||||
media_player_.Create(nullptr, mojo::MakeRequest<::media::MediaPlayer>(
|
||||
client_handle.Pass()));
|
||||
}
|
||||
if (service_name == ::media::MediaService::Name_) {
|
||||
media_service_.Create(nullptr, mojo::MakeRequest<::media::MediaService>(
|
||||
client_handle.Pass()));
|
||||
}
|
||||
#endif
|
||||
#if !TARGET_OS_IPHONE
|
||||
if (service_name == TestHarness::Name_) {
|
||||
@@ -53,6 +63,8 @@ class PlatformServiceProvider : public mojo::ServiceProvider {
|
||||
mojo::NetworkServiceFactory network_;
|
||||
#if TARGET_OS_IPHONE
|
||||
sky::services::keyboard::KeyboardServiceFactory keyboard_;
|
||||
sky::services::media::MediaPlayerFactory media_player_;
|
||||
sky::services::media::MediaServiceFactory media_service_;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user