├── README.md
├── android-plugin-source
├── AndroidManifest.xml
├── libs
│ ├── android-support-v4.jar
│ └── classes.jar
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ └── ads_media_controller.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── insthync
│ └── unityvideoview
│ ├── AdsMediaController.java
│ └── VideoViewPlugin.java
└── unity3d-project
└── Assets
├── Plugins
├── Android.meta
├── Android
│ ├── AndroidManifest.xml
│ ├── AndroidManifest.xml.meta
│ ├── android-support-v4.jar
│ ├── android-support-v4.jar.meta
│ ├── res.meta
│ └── res
│ │ ├── layout.meta
│ │ ├── layout
│ │ ├── ads_media_controller.xml
│ │ └── ads_media_controller.xml.meta
│ │ └── values.meta
├── MediaPlayer.meta
├── MediaPlayer
│ ├── IMediaPlayerAndroid.cs
│ ├── IMediaPlayerAndroid.cs.meta
│ ├── IMediaPlayerIOS.cs
│ ├── IMediaPlayerIOS.cs.meta
│ ├── IMediaPlayerNull.cs
│ ├── IMediaPlayerNull.cs.meta
│ ├── MediaPlayerBehavior.cs
│ ├── MediaPlayerBehavior.cs.meta
│ ├── MediaPlayerInterface.cs
│ └── MediaPlayerInterface.cs.meta
├── iOS.meta
└── iOS
│ ├── VideoView.mm
│ └── VideoView.mm.meta
└── Scripts
├── MediaPlayerTest.cs
└── MediaPlayerTest.cs.meta
/README.md:
--------------------------------------------------------------------------------
1 | unity3d-videoplayer-plugin
2 | ==========================
3 |
4 | Unity3d video player plugin for iOS and Android design for Advertisment
5 |
6 | You can see how to implement plugin via sample source located in "/unity3d-project/Assets/Scripts/MediaPlayerTest.cs"
--------------------------------------------------------------------------------
/android-plugin-source/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android-plugin-source/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/android-plugin-source/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/android-plugin-source/libs/classes.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/android-plugin-source/libs/classes.jar
--------------------------------------------------------------------------------
/android-plugin-source/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-18
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/android-plugin-source/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/android-plugin-source/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-plugin-source/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/android-plugin-source/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-plugin-source/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/android-plugin-source/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-plugin-source/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/android-plugin-source/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-plugin-source/res/layout/ads_media_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
12 |
13 |
19 |
20 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
41 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/android-plugin-source/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/android-plugin-source/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/android-plugin-source/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MediaPlayerUnity
4 |
5 |
--------------------------------------------------------------------------------
/android-plugin-source/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/android-plugin-source/src/com/insthync/unityvideoview/AdsMediaController.java:
--------------------------------------------------------------------------------
1 | /*
2 | MythDroid: Android MythTV Remote
3 | Copyright (C) 2009-2010 foobum@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | package com.insthync.unityvideoview;
20 |
21 | import java.lang.ref.WeakReference;
22 | import java.util.Locale;
23 |
24 | import android.content.Context;
25 | import android.content.res.Resources;
26 | import android.graphics.Rect;
27 | import android.media.AudioManager;
28 | import android.os.Handler;
29 | import android.os.Message;
30 | import android.view.Gravity;
31 | import android.view.KeyEvent;
32 | import android.view.LayoutInflater;
33 | import android.view.MotionEvent;
34 | import android.view.View;
35 | import android.widget.Button;
36 | import android.widget.ImageButton;
37 | import android.widget.MediaController;
38 | import android.widget.PopupWindow;
39 | import android.widget.SeekBar;
40 | import android.widget.SeekBar.OnSeekBarChangeListener;
41 | import android.widget.TextView;
42 |
43 | import java.util.Formatter;
44 |
45 | /**
46 | * A view containing controls for a MediaPlayer.
47 | */
48 | public class AdsMediaController extends MediaController {
49 | private Resources mResource;
50 | private MediaPlayerControl player;
51 | private Context ctx;
52 | private PopupWindow popupWindow;
53 | private View anchor, rootView;
54 | private SeekBar progress;
55 | private TextView playTime, titleView;
56 | private Button closeButton;
57 | private String title;
58 | private int duration;
59 | private boolean showing, dragging;
60 | private AudioManager audioMgr;
61 | private StringBuilder sb;
62 | private Formatter formatter;
63 | private MessageHandler handler;
64 | private View.OnClickListener closeListener;
65 |
66 | private static final int timeout = 3000, FADE_OUT = 1, SHOW_PROGRESS = 2;
67 |
68 | /**
69 | * Constructor
70 | * @param context Context
71 | */
72 | public AdsMediaController(Context context) {
73 | super(context, null);
74 | if (initController(context))
75 | initFloatingWindow();
76 | handler = new MessageHandler(this);
77 | mResource = getResources();
78 | }
79 |
80 | @Override
81 | public void setAnchorView(View view) {
82 | anchor = view;
83 | removeAllViews();
84 | rootView = makeControllerView();
85 | initControllerView(rootView);
86 | popupWindow.setContentView(rootView);
87 | popupWindow.setWidth(LayoutParams.FILL_PARENT);
88 | popupWindow.setHeight(LayoutParams.WRAP_CONTENT);
89 | }
90 |
91 | @Override
92 | public void show() {
93 | show(timeout);
94 | }
95 |
96 | @Override
97 | public void show(int timeout) {
98 |
99 | if (!showing && anchor != null && anchor.getWindowToken() != null) {
100 |
101 | int[] location = new int[2];
102 |
103 | anchor.getLocationOnScreen(location);
104 | Rect anchorRect =
105 | new Rect(
106 | location[0], location[1],
107 | location[0] + anchor.getWidth(),
108 | location[1] + anchor.getHeight()
109 | );
110 |
111 | popupWindow.setAnimationStyle(
112 | android.R.style.Animation_Translucent
113 | );
114 | popupWindow.showAtLocation(
115 | anchor, Gravity.NO_GRAVITY,
116 | anchorRect.left, anchorRect.bottom
117 | );
118 |
119 | showing = true;
120 |
121 | }
122 |
123 | updatePausePlay();
124 | handler.sendEmptyMessage(SHOW_PROGRESS);
125 |
126 | if (timeout != 0) {
127 | handler.removeMessages(FADE_OUT);
128 | handler.sendMessageDelayed(
129 | handler.obtainMessage(FADE_OUT), timeout
130 | );
131 | }
132 |
133 | }
134 |
135 | @Override
136 | public boolean onTouchEvent(MotionEvent event) {
137 | show(timeout);
138 | return true;
139 | }
140 |
141 | @Override
142 | public boolean onTrackballEvent(MotionEvent ev) {
143 | show(timeout);
144 | return false;
145 | }
146 |
147 | @Override
148 | public boolean dispatchKeyEvent(KeyEvent event) {
149 |
150 | int keyCode = event.getKeyCode();
151 |
152 | if (
153 | event.getRepeatCount() == 0 &&
154 | (
155 | keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
156 | keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE ||
157 | keyCode == KeyEvent.KEYCODE_SPACE
158 | )
159 | ) {
160 | doPauseResume();
161 | show(timeout);
162 | return true;
163 | }
164 |
165 | if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
166 | if (player.isPlaying()) {
167 | player.pause();
168 | updatePausePlay();
169 | }
170 | return true;
171 | }
172 |
173 | if (
174 | keyCode == KeyEvent.KEYCODE_BACK ||
175 | keyCode == KeyEvent.KEYCODE_MENU
176 | ) {
177 | hide();
178 | return true;
179 | }
180 |
181 | show(timeout);
182 |
183 | return super.dispatchKeyEvent(event);
184 |
185 | }
186 |
187 | @Override
188 | public boolean isShowing() {
189 | return showing;
190 | }
191 |
192 | @Override
193 | public void hide() {
194 |
195 | if (anchor == null) return;
196 |
197 | if (showing) {
198 | try {
199 | handler.removeMessages(SHOW_PROGRESS);
200 | popupWindow.dismiss();
201 | } catch (IllegalArgumentException ex) {}
202 | showing = false;
203 | }
204 |
205 | }
206 |
207 | @Override
208 | public void setEnabled(boolean enabled) {
209 | if (progress != null)
210 | progress.setEnabled(enabled);
211 | super.setEnabled(enabled);
212 | }
213 |
214 | @Override
215 | public void setMediaPlayer(MediaPlayerControl player) {
216 | this.player = player;
217 | updatePausePlay();
218 | }
219 |
220 | /**
221 | * Set the title of the program / video
222 | * @param name String containing title of program or video
223 | */
224 | public void setTitle(String name) {
225 | title = name;
226 | if (titleView != null)
227 | titleView.setText(title);
228 | }
229 |
230 | /**
231 | * Set an OnClickListener for the "Move To" button
232 | * @param listener View.OnLickListener callback
233 | */
234 | public void setCloseListener(View.OnClickListener listener) {
235 | closeListener = listener;
236 | if (closeButton != null)
237 | closeButton.setOnClickListener(closeListener);
238 | }
239 |
240 | protected View makeControllerView() {
241 | return (
242 | (LayoutInflater)
243 | ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
244 | ).inflate(mResource.getIdentifier("ads_media_controller", "layout", ctx.getPackageName()), this);
245 | }
246 |
247 | private static class MessageHandler extends Handler {
248 |
249 | private final WeakReference target;
250 |
251 | MessageHandler(AdsMediaController mc) {
252 | target = new WeakReference(mc);
253 | }
254 |
255 | @Override
256 | public void handleMessage(Message msg) {
257 |
258 | AdsMediaController mc = target.get();
259 |
260 | long pos;
261 | switch (msg.what) {
262 | case FADE_OUT:
263 | mc.hide();
264 | break;
265 | case SHOW_PROGRESS:
266 | pos = mc.setProgress();
267 | if (!mc.dragging && mc.showing) {
268 | msg = obtainMessage(SHOW_PROGRESS);
269 | sendMessageDelayed(msg, 1000 - (pos % 1000));
270 | mc.updatePausePlay();
271 | }
272 | break;
273 | }
274 | }
275 |
276 | }
277 |
278 | private void initControllerView(View v) {
279 |
280 | progress = (SeekBar)v.findViewById(mResource.getIdentifier("mctrlProgress", "id", ctx.getPackageName()));
281 | if (progress != null) {
282 | progress.setOnSeekBarChangeListener(seekListener);
283 | progress.setThumbOffset(1);
284 | progress.setMax(1000);
285 | }
286 |
287 | playTime = (TextView)v.findViewById(mResource.getIdentifier("mctrlPlayTime", "id", ctx.getPackageName()));
288 | titleView = (TextView)v.findViewById(mResource.getIdentifier("mctrlTitle", "id", ctx.getPackageName()));
289 | if (titleView != null)
290 | titleView.setText(title);
291 |
292 | closeButton = (Button)v.findViewById(mResource.getIdentifier("mctrlCloseButton", "id", ctx.getPackageName()));
293 | if (closeButton != null && closeListener != null)
294 | closeButton.setOnClickListener(closeListener);
295 | }
296 |
297 | private long setProgress() {
298 |
299 | if (player == null || dragging)
300 | return 0;
301 |
302 | int position = player.getCurrentPosition();
303 | int duration = player.getDuration();
304 | if (progress != null) {
305 | if (duration > 0) {
306 | int pos = 1000 * position / duration;
307 | progress.setProgress(pos);
308 | }
309 | int percent = player.getBufferPercentage();
310 | progress.setSecondaryProgress(percent * 10);
311 | }
312 |
313 | this.duration = duration;
314 |
315 | if (playTime != null)
316 | playTime.setText(strTime(position) + " / " + strTime(duration));
317 |
318 | return position;
319 | }
320 |
321 | private boolean initController(Context context) {
322 | ctx = context;
323 | audioMgr = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
324 | return true;
325 | }
326 |
327 | private void initFloatingWindow() {
328 | popupWindow = new PopupWindow(ctx);
329 | popupWindow.setFocusable(false);
330 | popupWindow.setBackgroundDrawable(null);
331 | popupWindow.setOutsideTouchable(true);
332 | sb = new StringBuilder();
333 | formatter = new Formatter(sb, Locale.getDefault());
334 | }
335 |
336 | private View.OnClickListener pauseListener = new View.OnClickListener() {
337 | @Override
338 | public void onClick(View v) {
339 | doPauseResume();
340 | show(timeout);
341 | }
342 | };
343 |
344 | private void updatePausePlay() {
345 | if (rootView == null)
346 | return;
347 | }
348 |
349 | private void doPauseResume() {
350 | if (player.isPlaying())
351 | player.pause();
352 | else
353 | player.start();
354 | updatePausePlay();
355 | }
356 |
357 | private String strTime(int time) {
358 |
359 | int totalSeconds = time / 1000;
360 | int seconds = totalSeconds % 60;
361 | int minutes = (totalSeconds / 60) % 60;
362 | int hours = totalSeconds / 3600;
363 |
364 | sb.setLength(0);
365 | if (hours > 0)
366 | return formatter.format(
367 | "%d:%02d:%02d", hours, minutes, seconds //$NON-NLS-1$
368 | ).toString();
369 | return formatter.format("%02d:%02d", minutes, seconds).toString(); //$NON-NLS-1$
370 |
371 | }
372 |
373 | private OnSeekBarChangeListener seekListener =
374 | new OnSeekBarChangeListener() {
375 |
376 | @Override
377 | public void onStartTrackingTouch(SeekBar bar) {
378 | dragging = true;
379 | show(3600000);
380 | handler.removeMessages(SHOW_PROGRESS);
381 | }
382 |
383 | @Override
384 | public void onProgressChanged(
385 | SeekBar bar, int progress, boolean fromuser
386 | ) {
387 | if (!fromuser) return;
388 | int newposition = (duration * progress) / 1000;
389 | String time = strTime(newposition);
390 |
391 | if (playTime != null)
392 | playTime.setText(time + " / " + strTime(duration));
393 | }
394 |
395 | @Override
396 | public void onStopTrackingTouch(SeekBar bar) {
397 | show(timeout);
398 | handler.removeMessages(SHOW_PROGRESS);
399 | audioMgr.setStreamMute(AudioManager.STREAM_MUSIC, false);
400 | dragging = false;
401 | handler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000);
402 | player.seekTo((bar.getProgress() * duration) / 1000);
403 | }
404 |
405 | };
406 |
407 | }
--------------------------------------------------------------------------------
/android-plugin-source/src/com/insthync/unityvideoview/VideoViewPlugin.java:
--------------------------------------------------------------------------------
1 | package com.insthync.unityvideoview;
2 | import java.io.IOException;
3 |
4 | import com.unity3d.player.UnityPlayer;
5 |
6 | import android.app.Activity;
7 | import android.graphics.Color;
8 | import android.media.MediaPlayer;
9 | import android.util.Log;
10 | import android.view.SurfaceHolder;
11 | import android.view.View;
12 | import android.view.ViewGroup.LayoutParams;
13 | import android.widget.FrameLayout;
14 | import android.widget.MediaController;
15 | import android.widget.RelativeLayout;
16 | import android.widget.VideoView;
17 |
18 |
19 | public class VideoViewPlugin implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, SurfaceHolder.Callback {
20 | private static final String TAG = "UnityMediaPlayer";
21 | private static RelativeLayout layout = null;
22 | private VideoView videoView;
23 | private AdsMediaController mediaController;
24 | private String videoURL = "";
25 | private String gameObject = "";
26 | private int currentVideoPosition = 0;
27 | public void Init(final String gameObject, final String title, final String videoURL)
28 | {
29 | this.gameObject = gameObject;
30 | this.videoURL = videoURL;
31 | final Activity a = UnityPlayer.currentActivity;
32 | a.runOnUiThread(new Runnable() {
33 |
34 | public void run() {
35 | Destroy();
36 |
37 | if (layout == null) {
38 | layout = new RelativeLayout(a);
39 | RelativeLayout.LayoutParams layoutParams;
40 | layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
41 | a.addContentView(layout, layoutParams);
42 | layout.setBackgroundColor(Color.BLACK);
43 | }
44 | layout.setVisibility(View.VISIBLE);
45 | layout.setFocusable(true);
46 | layout.setFocusableInTouchMode(true);
47 |
48 | videoView = new VideoView(a);
49 | videoView.setVideoPath(videoURL);
50 | videoView.setOnCompletionListener(VideoViewPlugin.this);
51 | videoView.setOnPreparedListener(VideoViewPlugin.this);
52 | videoView.setOnErrorListener(VideoViewPlugin.this);
53 | videoView.setZOrderMediaOverlay(true);
54 | if (mediaController == null) {
55 | mediaController = new AdsMediaController(a);
56 | }
57 | mediaController.setTitle(title);
58 | mediaController.setCloseListener(closeListener);
59 | mediaController.setMediaPlayer(videoView);
60 | videoView.setMediaController(mediaController);
61 |
62 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
63 | layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, -1);
64 | videoView.setLayoutParams(layoutParams);
65 |
66 | layout.addView(videoView);
67 |
68 | videoView.getHolder().addCallback(VideoViewPlugin.this);
69 | }
70 | });
71 | }
72 |
73 | private View.OnClickListener closeListener = new View.OnClickListener() {
74 | @Override
75 | public void onClick(View v) {
76 | UnityPlayer.UnitySendMessage( gameObject , "onVideoClose", "" );
77 | Destroy();
78 | }
79 | };
80 |
81 | @Override
82 | public void onCompletion(MediaPlayer mediaPlayer) {
83 | Log.d(TAG, "onCompletion called");
84 | UnityPlayer.UnitySendMessage( gameObject , "onVideoFinish", "" );
85 | Destroy();
86 | }
87 |
88 | @Override
89 | public void onPrepared(MediaPlayer mediaPlayer) {
90 | Log.d(TAG, "onPrepared called");
91 | mediaPlayer.start();
92 | if (currentVideoPosition > 0) {
93 | mediaPlayer.seekTo(currentVideoPosition);
94 | } else {
95 | mediaPlayer.seekTo(0);
96 | }
97 | }
98 |
99 | @Override
100 | public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
101 | // TODO Auto-generated method stub
102 | Log.d(TAG, "onError called");
103 | Destroy();
104 | return false;
105 | }
106 |
107 | public void Destroy()
108 | {
109 | Activity a = UnityPlayer.currentActivity;
110 | a.runOnUiThread(new Runnable() {
111 | public void run() {
112 | if (videoView != null) {
113 | videoView.stopPlayback();
114 | layout.removeView(videoView);
115 | videoView = null;
116 | }
117 | if (layout != null) {
118 | layout.setFocusable(false);
119 | layout.setFocusableInTouchMode(false);
120 | layout.setVisibility(View.GONE);
121 | }
122 | currentVideoPosition = 0;
123 | }
124 | });
125 | }
126 |
127 | @Override
128 | public void surfaceChanged(SurfaceHolder holder, int format, int width,
129 | int height) {
130 | Log.d(TAG, "surfaceChanged called");
131 | }
132 |
133 | @Override
134 | public void surfaceCreated(SurfaceHolder holder) {
135 | Log.d(TAG, "surfaceCreated called");
136 | }
137 |
138 | @Override
139 | public void surfaceDestroyed(SurfaceHolder holder) {
140 | Log.d(TAG, "surfaceDestroyed called");
141 | currentVideoPosition = videoView.getCurrentPosition();
142 | videoView.stopPlayback();
143 | videoView.seekTo(currentVideoPosition);
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 49324747d6d89a84695cb2ae0304915c
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
14 |
15 |
16 |
17 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/AndroidManifest.xml.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: cd73acf6e4e76a941ba0855109456433
3 | TextScriptImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insthync/unity3d-videoplayer-plugin/25f9f1f2ce3a933231cd5dc5fb2cbec2b2b3a01e/unity3d-project/Assets/Plugins/Android/android-support-v4.jar
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/android-support-v4.jar.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2cee885f0e231cf4fb0bda4377e114d6
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/res.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 317b7e2aadf0883438d507daf27aa2cf
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/res/layout.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a3585fcda4ab5ee4799c396bf835053c
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/res/layout/ads_media_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
12 |
13 |
19 |
20 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
41 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/res/layout/ads_media_controller.xml.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 43c568eaf1773204fa7ec249dbe1b395
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/Android/res/values.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 094b64c9a733c6b43a12f37b9fe4d0bb
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 482ecb43b71e5ff4d8009a53154919ae
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/IMediaPlayerAndroid.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | #if UNITY_ANDROID
5 | public class IMediaPlayerAndroid : IMediaPlayer {
6 |
7 | AndroidJavaObject mediaPlayer = null;
8 |
9 | public void Init( string name, string title, string url )
10 | {
11 | mediaPlayer = new AndroidJavaObject( "com.insthync.unityvideoview.VideoViewPlugin" );
12 | SafeCall( "Init", name, title, url );
13 | }
14 |
15 | public void Term()
16 | {
17 | SafeCall( "Destroy" );
18 | }
19 |
20 | private void SafeCall( string method, params object[] args )
21 | {
22 | if( mediaPlayer != null )
23 | {
24 | mediaPlayer.Call( method, args );
25 | }
26 | else
27 | {
28 | Debug.LogError( "mediaPlayer is not created. you check is a call 'Init' method" );
29 | }
30 | }
31 | }
32 | #endif
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/IMediaPlayerAndroid.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 49f7284425fc227428d522156cf8cf5c
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/IMediaPlayerIOS.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.Runtime.InteropServices;
6 |
7 | #if UNITY_IPHONE
8 | public class IMediaPlayerIOS : IMediaPlayer {
9 |
10 | private IntPtr instance;
11 |
12 | #region Interface Method
13 | public void Init( string name, string title, string url )
14 | {
15 | instance = _VideoViewPlugin_Init( name, title, url );
16 | }
17 | public void Term()
18 | {
19 | _VideoViewPlugin_Destroy( instance );
20 | }
21 |
22 | #endregion
23 |
24 | #region Native Access Method
25 | [DllImport("__Internal")]
26 | private static extern IntPtr _VideoViewPlugin_Init(string name, string title, string url);
27 |
28 | [DllImport("__Internal")]
29 | private static extern int _VideoViewPlugin_Destroy(IntPtr instance);
30 |
31 | #endregion
32 | }
33 | #endif
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/IMediaPlayerIOS.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 15f0c27b7eddef14c9101f07c96afa0a
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/IMediaPlayerNull.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | public class IMediaPlayerNull : IMediaPlayer {
5 | public void Init( string name, string title, string url ){}
6 | public void Term(){}
7 | }
8 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/IMediaPlayerNull.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 50e95e9d977a65843b5edb0ff7e2f664
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/MediaPlayerBehavior.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | public class MediaPlayerBehavior : MonoBehaviour {
5 |
6 | IMediaPlayer videoView;
7 | IMediaPlayerCallback callback;
8 |
9 | #region Method
10 |
11 | public void Awake()
12 | {
13 |
14 | #if UNITY_ANDROID
15 | videoView = new IMediaPlayerAndroid();
16 | #elif UNITY_IPHONE
17 | videoView = new IMediaPlayerIOS();
18 | #else
19 | videoView = new IMediaPlayerNull();
20 | #endif
21 |
22 | callback = null;
23 | }
24 |
25 | public void Init(string title, string url)
26 | {
27 | videoView.Init( name, title, url );
28 | }
29 |
30 | public void OnDestroy()
31 | {
32 | videoView.Term();
33 | }
34 |
35 | public void setCallback( IMediaPlayerCallback _callback )
36 | {
37 | callback = _callback;
38 | }
39 |
40 | public void onVideoFinish( string data )
41 | {
42 | if( callback != null )
43 | {
44 | callback.onVideoFinish( data );
45 | }
46 | }
47 |
48 | public void onVideoClose( string data )
49 | {
50 | if( callback != null )
51 | {
52 | callback.onVideoClose( data );
53 | }
54 | }
55 |
56 | #endregion
57 | }
58 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/MediaPlayerBehavior.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ba064dd434f6a7a4fa04dddcf28dd112
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/MediaPlayerInterface.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | public interface IMediaPlayer
5 | {
6 |
7 | void Init( string name, string title, string url );
8 | void Term();
9 |
10 | }
11 |
12 | public interface IMediaPlayerCallback
13 | {
14 | void onVideoFinish( string data );
15 | void onVideoClose( string data );
16 | }
17 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/MediaPlayer/MediaPlayerInterface.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6e71fef367d6503438bb2c0e3aa77b63
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/iOS.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e77226de90eb7684b8d8e72cffe507c9
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/iOS/VideoView.mm:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | extern UIViewController *UnityGetGLViewController();
5 |
6 | @interface VideoViewPlugin : NSObject
7 | {
8 | UIView *videoViewContainer;
9 | UIView *topBackground;
10 | UIView *bottomBackground;
11 | UILabel *videoTitleLabel;
12 | UILabel *videoTimeLabel;
13 | UIButton *closeButton;
14 | MPMoviePlayerController *videoView;
15 | NSString *gameObjectName;
16 | NSTimer *durationUpdateTimer;
17 | BOOL closeClicked;
18 | }
19 | @end
20 |
21 | @implementation VideoViewPlugin
22 |
23 | - (id)initWithGameObjectName:(const char *)gameObjectName_ withTitle:(const char *)title_ withURL:(const char *)videoURL_
24 | {
25 | self = [super init];
26 |
27 | closeClicked = NO;
28 | UIView *view = UnityGetGLViewController().view;
29 | videoViewContainer = [[UIView alloc] initWithFrame:view.frame];
30 | videoViewContainer.hidden = NO;
31 | [view addSubview:videoViewContainer];
32 | NSString *title = [[NSString stringWithUTF8String:title_] retain];
33 | NSString *videoURL = [[NSString stringWithUTF8String:videoURL_] retain];
34 | videoView = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:videoURL]];
35 | [videoViewContainer addSubview:[videoView view]];
36 | videoView.controlStyle = MPMovieControlStyleNone;
37 | videoView.repeatMode = MPMovieRepeatModeNone;
38 | videoView.shouldAutoplay=YES;
39 | [videoView play];
40 |
41 |
42 | [[NSNotificationCenter defaultCenter] addObserver:self
43 | selector:@selector(moviePlayBackDidFinish:)
44 | name:MPMoviePlayerPlaybackDidFinishNotification
45 | object:videoView];
46 | [[NSNotificationCenter defaultCenter] addObserver:self
47 | selector:@selector(didRotate:)
48 | name:UIDeviceOrientationDidChangeNotification
49 | object:nil];
50 | durationUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1
51 | target:self
52 | selector:@selector(currentTimeUpdate:)
53 | userInfo:nil
54 | repeats:YES];
55 |
56 | topBackground = [[UIView alloc] init];
57 | topBackground.backgroundColor = [UIColor colorWithRed:200/255 green:200/255 blue:200/255 alpha:0.8];
58 | [view addSubview:topBackground];
59 |
60 | bottomBackground = [[UIView alloc] init];
61 | bottomBackground.backgroundColor = [UIColor colorWithRed:200/255 green:200/255 blue:200/255 alpha:0.8];
62 | [view addSubview:bottomBackground];
63 |
64 | videoTitleLabel = [[UILabel alloc] init];
65 | [videoTitleLabel setText:title];
66 | videoTitleLabel.textColor = [UIColor whiteColor];
67 | [view addSubview:videoTitleLabel];
68 |
69 | videoTimeLabel = [[UILabel alloc] init];
70 | [videoTimeLabel setText:@""];
71 | videoTimeLabel.textColor = [UIColor whiteColor];
72 | videoTimeLabel.textAlignment = NSTextAlignmentRight;
73 | [view addSubview:videoTimeLabel];
74 |
75 | closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
76 | [closeButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
77 | closeButton.backgroundColor = [UIColor whiteColor];
78 | closeButton.layer.borderColor = [UIColor grayColor].CGColor;
79 | closeButton.layer.borderWidth = 0.5f;
80 | closeButton.layer.cornerRadius = 5.0f;
81 | [closeButton addTarget:self
82 | action:@selector(closeButtonTouched:)
83 | forControlEvents:UIControlEventTouchUpInside];
84 | [closeButton setTitle:@"Close" forState:UIControlStateNormal];
85 | [view addSubview:closeButton];
86 |
87 | [self setupScreen];
88 | gameObjectName = [[NSString stringWithUTF8String:gameObjectName_] retain];
89 | return self;
90 | }
91 |
92 | - (void)dealloc
93 | {
94 |
95 | [[NSNotificationCenter defaultCenter] removeObserver:self
96 | name:MPMoviePlayerPlaybackDidFinishNotification
97 | object:videoView];
98 | [[NSNotificationCenter defaultCenter] removeObserver:self
99 | name:UIDeviceOrientationDidChangeNotification
100 | object:nil];
101 |
102 | [topBackground removeFromSuperview];
103 | [topBackground release];
104 | [bottomBackground removeFromSuperview];
105 | [bottomBackground release];
106 | [videoTitleLabel removeFromSuperview];
107 | [videoTitleLabel release];
108 | [videoTimeLabel removeFromSuperview];
109 | [videoTimeLabel release];
110 | [closeButton removeFromSuperview];
111 | [closeButton release];
112 |
113 | [videoView stop];
114 | [videoView.view removeFromSuperview];
115 |
116 | [videoViewContainer removeFromSuperview];
117 | [videoViewContainer release];
118 | [gameObjectName release];
119 | [super dealloc];
120 | }
121 |
122 | -(NSString *)secondsToMMSS:(double)seconds
123 | {
124 | NSInteger time = floor(seconds);
125 | NSInteger hh = time / 3600;
126 | NSInteger mm = (time / 60) % 60;
127 | NSInteger ss = time % 60;
128 | if(hh > 0)
129 | return [NSString stringWithFormat:@"%d:%02i:%02i",hh,mm,ss];
130 | else
131 | return [NSString stringWithFormat:@"%02i:%02i",mm,ss];
132 |
133 | }
134 |
135 | -(void)currentTimeUpdate:(NSTimer *)sender
136 | {
137 | NSString *currentTimeText = [self secondsToMMSS:videoView.currentPlaybackTime];
138 | NSString *videoDurationText = [self secondsToMMSS:videoView.duration];
139 | videoTimeLabel.text = [NSString stringWithFormat:@"%@ / %@",currentTimeText,videoDurationText];
140 | }
141 |
142 | - (void) moviePlayBackDidFinish:(NSNotification*)notification {
143 | if (!closeClicked) {
144 | UnitySendMessage( [gameObjectName UTF8String], "onVideoFinish", "");
145 | } else {
146 | UnitySendMessage( [gameObjectName UTF8String], "onVideoClose", "");
147 | }
148 | NSLog(@"Video ended");
149 | [self dealloc];
150 | }
151 |
152 | -(void) closeButtonTouched:(UIButton *) sender {
153 | closeClicked = YES;
154 | NSLog(@"Close button touched");
155 | [videoView stop];
156 | }
157 |
158 | -(void) didRotate:(NSNotification*)notification {
159 | NSLog(@"rotation changed");
160 | [self setupScreen];
161 | }
162 |
163 | - (void)setupScreen
164 | {
165 | UIView *view = UnityGetGLViewController().view;
166 |
167 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
168 |
169 | CGRect frame = view.frame;
170 | int width = frame.size.width;
171 | int height = frame.size.height;
172 | int x = frame.origin.x;
173 | int y = frame.origin.y;
174 |
175 | CGRect labelFrame = view.frame;
176 | CGRect buttonFrame = view.frame;
177 | CGRect topBGFrame = view.frame;
178 | CGRect bottomBGFrame = view.frame;
179 | CGRect timeLabelFrame = view.frame;
180 |
181 | if (UIInterfaceOrientationIsPortrait(interfaceOrientation))
182 | {
183 | frame.size.width = width;
184 | frame.size.height = height;
185 | frame.origin.x = x;
186 | frame.origin.y = y;
187 |
188 | labelFrame.origin.x = 5;
189 | labelFrame.origin.y = 0;
190 | labelFrame.size.width = width - 70;
191 | labelFrame.size.height = 40;
192 |
193 | buttonFrame.origin.x = width - 65;
194 | buttonFrame.origin.y = 5;
195 | buttonFrame.size.width = 60;
196 | buttonFrame.size.height = 25;
197 |
198 | topBGFrame.size.width = width;
199 | topBGFrame.size.height = 40;
200 | topBGFrame.origin.x = 0;
201 | topBGFrame.origin.y = 0;
202 |
203 | bottomBGFrame.size.width = width;
204 | bottomBGFrame.size.height = 40;
205 | bottomBGFrame.origin.x = 0;
206 | bottomBGFrame.origin.y = height - 40;
207 |
208 | timeLabelFrame.size.width = width - 5;
209 | timeLabelFrame.size.height = 40;
210 | timeLabelFrame.origin.x = 0;
211 | timeLabelFrame.origin.y = height - 45;
212 | } else {
213 | frame.size.width = height;
214 | frame.size.height = width;
215 | frame.origin.x = y;
216 | frame.origin.y = x;
217 |
218 | labelFrame.origin.x = 5;
219 | labelFrame.origin.y = 0;
220 | labelFrame.size.width = height - 70;
221 | labelFrame.size.height = 40;
222 |
223 | buttonFrame.origin.x = height - 65;
224 | buttonFrame.origin.y = 5;
225 | buttonFrame.size.width = 60;
226 | buttonFrame.size.height = 25;
227 |
228 | topBGFrame.size.width = height;
229 | topBGFrame.size.height = 40;
230 | topBGFrame.origin.x = 0;
231 | topBGFrame.origin.y = 0;
232 |
233 | bottomBGFrame.size.width = height;
234 | bottomBGFrame.size.height = 40;
235 | bottomBGFrame.origin.x = 0;
236 | bottomBGFrame.origin.y = width - 40;
237 |
238 | timeLabelFrame.size.width = height - 5;
239 | timeLabelFrame.size.height = 40;
240 | timeLabelFrame.origin.x = 0;
241 | timeLabelFrame.origin.y = width - 45;
242 | }
243 |
244 | videoTitleLabel.frame = labelFrame;
245 | closeButton.frame = buttonFrame;
246 | topBackground.frame = topBGFrame;
247 | bottomBackground.frame = bottomBGFrame;
248 | videoTimeLabel.frame = timeLabelFrame;
249 |
250 | videoViewContainer.frame = frame;
251 | [[videoView view] setFrame:[videoViewContainer bounds]];
252 | [videoViewContainer addSubview:[videoView view]];
253 | }
254 | @end
255 |
256 | extern "C" {
257 | void *_VideoViewPlugin_Init(const char *gameObjectName, const char *title, const char *videoURL);
258 | void _VideoViewPlugin_Destroy(void *instance);
259 | }
260 |
261 | void *_VideoViewPlugin_Init(const char *gameObjectName, const char *title, const char *videoURL)
262 | {
263 | id instance = [[VideoViewPlugin alloc] initWithGameObjectName:gameObjectName withTitle:title withURL:videoURL];
264 | return (void *)instance;
265 | }
266 |
267 | void _VideoViewPlugin_Destroy(void *instance)
268 | {
269 | VideoViewPlugin *videoViewPlugin = (VideoViewPlugin *)instance;
270 | [videoViewPlugin release];
271 | }
--------------------------------------------------------------------------------
/unity3d-project/Assets/Plugins/iOS/VideoView.mm.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: aeb70fa683b75437aad94044e03c7d4d
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Scripts/MediaPlayerTest.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | class CallBackTest : IMediaPlayerCallback {
5 | public void onVideoFinish( string data ) {
6 | Debug.Log("Video played, data: " + data);
7 | }
8 | public void onVideoClose( string data ) {
9 | Debug.Log("Video closed, data: " + data);
10 | }
11 | }
12 |
13 | public class MediaPlayerTest : MonoBehaviour {
14 |
15 | CallBackTest m_callback;
16 |
17 | // Use this for initialization
18 | void Start () {
19 |
20 | m_callback = new CallBackTest();
21 | MediaPlayerBehavior player = GetComponent();
22 |
23 | if( player != null )
24 | {
25 | player.Init( "Test title", "http://video-js.zencoder.com/oceans-clip.mp4");
26 | player.setCallback( m_callback );
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/unity3d-project/Assets/Scripts/MediaPlayerTest.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 20fce38e8028abd47b76d7f5617b0455
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------