埋め込みwebkitでのvideoタグ対応

8181 views
Skip to first unread message

アルバイト社員

unread,
Jan 31, 2011, 4:26:01 AM1/31/11
to 日本Androidの会
お世話になっております。
アルバイト社員と申します。


現在、html5のvideoタグによる、動画再生対応をしています。
3gpやmp4ファイルでもコーデックの違いで再生できたり出来なかったりすることに非常に苦しんでいます。
(IS03/Galaxy Sでテストを行っています。)

現在はデフォルトのブラウザを使用し、再生を行っていたのですが、
これからはWebvViewを埋め込み同様のことをしたいと考えています。

しかし、実装をしてみるとデフォルトのブラウザでは再生できたvideoタグのhtmlを読み込んでも再生が出来ません。

何か必要な処理があるのでしょうか?

・webView.getSettings().setJavaScriptEnabled(true);
・webView.getSettings().setPluginsEnabled(true);

は、行ってみましたが、だめでした。


どなたか、ご指南のほどよろしくお願いします。

Sasaki, Akira

unread,
Jan 31, 2011, 8:31:39 PM1/31/11
to android-g...@googlegroups.com
佐々木です。

ディフォルトのブラウザの設定項目です。
191-246行目にて、いろいろな設定をおこなっているので、videoタグ
関連はHTML5関連の項目を有効にすると動くようになるかもしれないと
思います。

OS2.2
http://android.git.kernel.org/?p=platform/packages/apps/Browser.git;a=blob;f=src/com/android/browser/BrowserSettings.java;h=3791eb07f1cffec4c7254ef670cd883dda847195;hb=93265e4ba4521ed8e6f685fec38ee0f2fd9f3697

OS2.3
http://android.git.kernel.org/?p=platform/packages/apps/Browser.git;a=blob;f=src/com/android/browser/BrowserSettings.java;h=3791eb07f1cffec4c7254ef670cd883dda847195;hb=93265e4ba4521ed8e6f685fec38ee0f2fd9f3697


よろしくお願いします。

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
株式会社GClue ( http://www.gclue.com )

代表取締役
佐々木 陽 ( ak...@gclue.jp )

〒965-0037
福島県会津若松市中央3丁目6-32 中央ビル3F

PS3: gclue_aizu(TV会議用)
TEL:0242-22-6162
FAX:0242-22-6163
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

2011年1月31日18:26 アルバイト社員 <mmm.y...@gmail.com>:

> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>
>

ohisamallc

unread,
Jan 31, 2011, 10:00:38 PM1/31/11
to android-g...@googlegroups.com
山形のohisamaです。
山形は、今日も吹雪いています。

webkitとは、webviewを呼び出したんですよね。
android1.6しか知りませんが、webviewは、
その辺の再生プラグインの様なものを呼ばない仕様のようです。
自前で実装するしかないのでは。

以下は、前に作った野良アプリですが、
良かったら、動作確認して見てください。
http://yumeblog.dip.jp/test/1012310850.htm

アルバイト社員

unread,
Feb 1, 2011, 10:26:56 PM2/1/11
to 日本Androidの会
佐々木様

ありがとうございます。
現在、Browerアプリのソースを落とし、見ているところでございます。
videoタグ関連のところが幾つかあり、もう少し考える必要があるので、またわからないことがあった場合は
質問をさせていただこうと思います。

よろしくお願い致します。


On 2月1日, 午前10:31, "Sasaki, Akira" <ak...@gclue.jp> wrote:
> 佐々木です。
>
> ディフォルトのブラウザの設定項目です。
> 191-246行目にて、いろいろな設定をおこなっているので、videoタグ
> 関連はHTML5関連の項目を有効にすると動くようになるかもしれないと
> 思います。
>

> OS2.2http://android.git.kernel.org/?p=platform/packages/apps/Browser.git;a...
>
> OS2.3http://android.git.kernel.org/?p=platform/packages/apps/Browser.git;a...
>
> よろしくお願いします。
>
> □□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
> 株式会社GClue (http://www.gclue.com)


>
> 代表取締役
> 佐々木 陽 ( ak...@gclue.jp )
>
> 〒965-0037
> 福島県会津若松市中央3丁目6-32 中央ビル3F
>
> PS3: gclue_aizu(TV会議用)
> TEL:0242-22-6162
> FAX:0242-22-6163
> □□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
>

> 2011年1月31日18:26 アルバイト社員 <mmm.you...@gmail.com>:

アルバイト社員

unread,
Feb 1, 2011, 10:37:39 PM2/1/11
to 日本Androidの会
ohisama様

コメントありがとうございます。
アプリを端末にインストールさせていただきました。
しかし、IS03で試してみたのですが、動画は再生出来ませんでした。

実装のヒントがあれば教えていただきたいです。

よろしくお願い致します。


On 2月1日, 午後12:00, "ohisamallc" <peng...@mui.biglobe.ne.jp> wrote:
> 山形のohisamaです。
> 山形は、今日も吹雪いています。
>
> webkitとは、webviewを呼び出したんですよね。
> android1.6しか知りませんが、webviewは、
> その辺の再生プラグインの様なものを呼ばない仕様のようです。
> 自前で実装するしかないのでは。
>
> 以下は、前に作った野良アプリですが、
> 良かったら、動作確認して見てください。http://yumeblog.dip.jp/test/1012310850.htm
>
>
>
>
>
>
>
>
>
> > -----Original Message-----> From:android-g...@googlegroups.com> [mailto:android-g...@googlegroups.com]OnBehalf Of アルバイト社員

アルバイト社員

unread,
Feb 17, 2011, 3:47:27 AM2/17/11
to 日本Androidの会
お世話になっております。

アルバイト社員です。

解決出来ましたので、一応報告させていただきます。


WebChromeClientクラスを拡張しvideoタグ対応を実現できました。

WebChromeClient#onShowCustomView()で自動的にOSが適切なViewを選択して引数として渡してくれます。
メソッド内で、表示しているWebViewを隠し(GONE)、引数として受け取ったViewをセットします。

また、終了時はWbChromeClient#onHideCustomView()が呼ばれるので、表示したときと逆の処理
(WebViewの表示と先ほどセットしたCustomViewを隠す)をします。

簡単に言うと、このような感じになります。

以下,ソースです。

**********************************************************************************************************************
class EmbedWevChromClient extends WebChromeClient {

private View videoProgressView = null;
private CustomViewCallback customViewCallback = null;
private Bitmap defaultPoster = null;

@Override
public Bitmap getDefaultVideoPoster() {

// Videoタグのポスター属性が設定されていない場合表示する画像
Log.v(TAG, "getDefaultVideoPoster()");

// ビットマップ作成
if (defaultPoster == null) {
defaultPoster = BitmapFactory.decodeResource(
getResources(), R.drawable.gaaa);
}

return defaultPoster;

}

// カスタムビューが作成されたときに呼び出される。
// たとえば、videoタグが再生されたときなど
@Override
public void onShowCustomView(View view,
CustomViewCallback callback) {

Log.v(TAG, "chrom * onShowCustomView()");

// カスタムビューがすでにあるときは隠す
if (existCustomView()) {

// すでに表示されている場合は隠す
callback.onCustomViewHidden();
return;
}

// カスタムビューが無い場合

// WebViewを隠す
EmbedWebView.this.setVisibility(View.GONE);

// ルートに端末により選ばれたカスタムViewをセット
parentLayout.addView(view, FILL_PARENT_PARAMS);

// カスタムビューに選択されたViewをセット
customView = view;

// コールバックにセット
customViewCallback = callback;

// ルート要素を表示
parentLayout.setVisibility(View.VISIBLE);

}

@Override
public void onHideCustomView() {
Log.v(TAG, "chrom * onHideCustomView()");

// カスタムViewがなければなにもしない
if (!existCustomView()) {
return;
}

// カスタムViewを除去
parentLayout.removeView(customView);

// 隠す
customViewCallback.onCustomViewHidden();

customView = null;

// WebViewを表示
EmbedWebView.this.setVisibility(View.VISIBLE);

}

@Override
public View getVideoLoadingProgressView() {
Log.v(TAG, "getVideoLoadingProgressView()");

// プログレスバーがなければ作成
if (videoProgressView == null) {

// inflater取得
LayoutInflater inflater = (LayoutInflater) mActivityt
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

// View作成
videoProgressView = inflater.inflate(
R.layout.video_loading_layout, null);

}

// 作成したプログレスバーを返す
return videoProgressView;
}

}

***********************************************************************************************************************************


いじょうです。

分かりづらくて、申し訳ないです。


佐々木さん、ohisamaさんアドバイスありがとうございました。

hina

unread,
Aug 31, 2012, 9:01:39 AM8/31/12
to android-g...@googlegroups.com
お世話になります、hinaと申します。

1年以上前のスレッドですが、関連する質問なので投稿させて頂きます。

WebViewでvideoタグを含むhtmlを表示し、動画を再生するアプリを作成しています。

Android2.3ではこちらのスレッドの内容で動作したのですが、
Android3.x、4.xでは挙動が異なっていて困っています。

2.3
videoタグの動画をタップすると、
onShowCustomView()が呼び出されて、Viewの切り替え処理が呼ばれ、全画面で再生される。

3.x / 4.x
videoタグの動画をタップすると、
onShowCustomView()が呼び出されず、全画面にならずWebView内で再生される。
WebView内で再生中にクリアキー押下すると、バックグラウンドで再生継続し、制御できないのが問題。
確認端末:Galaxy Tab10.1LTE  / Galaxy Nexus


WebViewはこちらのコードを利用しました。
https://code.google.com/p/html5webview/ 

公式サイトにあるようにandroid:hardwareAccelerated="true"としています。
falseにすると画像が表示されず、音声のみ再生されます。挙動は変わらずです。
http://developer.android.com/intl/ja/reference/android/webkit/WebView.html 

HTML5 Video support

In order to support inline HTML5 video in your application, you need to have hardware acceleration turned on, and set a WebChromeClient. For full screen support, implementations of onShowCustomView(View, WebChromeClient.CustomViewCallback) and onHideCustomView() are required,getVideoLoadingProgressView() is optional.

WebChromeClientの各メソッドでブレイクしようとしたのですが、止まりませんでした。
処理が来ていないので、挙動が変わっているのだと思います。
・getDefaultVideoPoster()
・getVideoLoadingProgressView()
・onShowCustomView()


いろいろ試してみたのですが行き詰ってしまいました。
・ハードウェアアクセサレーターの影響??
・Androidのhtml5周りはまだバギー??
・WebChromeClientの処理が呼び出されないのはなぜ?
・実装方法がおかしい?

お知恵、情報など頂ければ幸いです。

以下、ソースコード抜粋。
AndroidManifest.xml
<manifest
    ・・・・・>
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:hardwareAccelerated="true"
>
        <activity
            android:name=".TestWebViewActivity"
android:hardwareAccelerated="true"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


TestWebViewActivity.java
public class TestWebViewActivity extends Activity {
HTML5WebView mWebView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new HTML5WebView(this);
        
        if (savedInstanceState != null) {
        mWebView.restoreState(savedInstanceState);
        } else {
        mWebView.loadUrl(loadUrl);
        }
        
        setContentView(mWebView.getLayout());
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mWebView.saveState(outState);
    }
    
    @Override
    public void onStop() {
    super.onStop();
    mWebView.stopLoading();
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mWebView.inCustomView()) {
            mWebView.hideCustomView();
            return true;
            }
    }
    return super.onKeyDown(keyCode, event);
    }
}


https://code.google.com/p/html5webview/ のHTML5WebView.java 初期化処理のみ転記
public class HTML5WebView extends WebView {
private void init(Context context) {
mContext = context;
Activity a = (Activity) mContext;
mLayout = new FrameLayout(context);
mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(a).inflate(R.layout.custom_screen, null);
mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.main_content);
mCustomViewContainer = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.fullscreen_custom_content);
mLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);

mWebChromeClient = new MyWebChromeClient();
setWebChromeClient(mWebChromeClient);
   
   
   setWebViewClient(new MyWebViewClient());
      
   // Configure the webview
   WebSettings s = getSettings();
   s.setBuiltInZoomControls(true);
   s.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
   s.setUseWideViewPort(true);
   s.setLoadWithOverviewMode(true);
   s.setSavePassword(true);
   s.setSaveFormData(true);
   s.setJavaScriptEnabled(true);
   
   // enable navigator.geolocation 
   s.setGeolocationEnabled(true);
   s.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");
   
   // enable Web Storage: localStorage, sessionStorage
   s.setDomStorageEnabled(true);
   
   mContentView.addView(this);
}
}

以上、よろしくお願い致します。


2011年2月17日木曜日 17時47分27秒 UTC+9 アルバイト社員:

XBG

unread,
Sep 1, 2012, 9:57:27 AM9/1/12
to android-g...@googlegroups.com
こんにちは。自作ブラウザの開発に関わるので、こちらでもエミュレータで試してみました。
どうやらAndroid3.x以降はVideoコントロールの全画面ボタンを押さないとonShowCustomView()は呼ばれてはいるんですがViewを渡してもらえないらしいです。
エミュレータとYouTubeでしか確認していませんが、再生中に全画面化ボタンを押すとAndroid2.x系と同じ動作になりました。
Android3.x系はもともと大画面のタブレット向けなので、それに合わせて自動で全画面にならないようにする処置と思われます。
実機での動作確認が行えていませんが、再生継続の問題についてはdispatchKeyEvent()やonPause()でイベントを拾い、WebChromeClient.CustomViewCallback#onHideCustomView()を呼べば大丈夫かと思います。
 
以下、実験に使用したWebChromeClientの3メソッドです。
onShowCustomView(View,int,WebChromeClient.CustomViewCallback)はAPI level 14が必要ですので、Android4.x以降向けにプロジェクトをコピーするなどして対処してください。
 
@Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
 Log.d("VIDEO","SHOW");
 customView = view;
 customViewCallback = callback;
   
 showVideo(customView);//このメソッドは親Activityにあります、ここで全画面化処理を行っています。省略
 super.onShowCustomView(view, callback);//なぜかここの順序を変えると全画面になってもすぐ戻ってしまいます
}  
  
/*Android4.x以降への対策用です。2度手間になるのでそのまま渡してます*/
@Override
public void onShowCustomView(View view, int requestedOrientation,
  CustomViewCallback callback) {
 // TODO Auto-generated method stub
 onShowCustomView(view, callback);
}
 
@Override
public void onHideCustomView() {
 // TODO Auto-generated method stub
 Log.d("VIDEO","ONHIDE");
 super.onHideCustomView();
 // viewを削除するための処理
  /*これまた親Activityにあります、ここで全画面を解除する処理を行っています。
 また全画面ボタンを押すまではViewもCallbackも渡っていないので
 メソッド内でtry~catchによる判定を行っています。これまた省略*/
 hideVideo();
}

2012年8月31日金曜日 22時01分39秒 UTC+9 hina:

hina

unread,
Sep 3, 2012, 12:31:11 AM9/3/12
to android-g...@googlegroups.com
返信ありがとうございます。回答遅くなりすみません。

実機(GN 4.0.4)で確認致しました。

お教え頂いた通り、
Videoコントロールの全画面ボタンを押すことでonShowCustomView()が呼ばれることを確認致しました。(2.3と同じ動作)
ありがとうございます。

再生継続する件ですが、こちらはうまく動作しませんでした。
(クリアキーでアプリ終了しても、バックグラウンド再生が継続した状態となります)

メインアクティビティのonPause()で以下の処理を行いました。
    @Override
    public void onPause() {
    super.onPause();
    mWebView.hideCustomView(); // 内部でonHideCustomView()を呼んでいる 
    mWebView.stopLoading();
    }

アプリ終了後もLogCat上で、MediaPlayerのログが出力されておりました。
別スレッドで動作しているのでしょうか。。

アプリ側で解決方法が思いつかないので、
HTML側を修正して全画面にできないか試してみます。
1.HTMLのvideoタグをタッチ
2.HTMLでVideoコントールの全画面ボタンと同じイベント発行
3.アプリでonShowCustomView()が呼ばれる

アプリだけで完結できればよいのですが、
ほかに良い方法ございましたら、アドバイス頂ければ幸いです。

kakajika

unread,
Sep 3, 2012, 2:23:31 AM9/3/12
to android-g...@googlegroups.com
hinaさん

こんにちは、kakajikaと申します。

動画の停止の件についてですが、
WebViewのonPause() メソッドを呼べば停止できると思います。

GingerBread以前では隠しメソッドになっているのでリフレクションを使えば呼び出せます。

WebView.class.getMethod("onPause", (Class[]) null).invoke(mWebView, (Object[]) null);


的はずれな回答だったらごめんなさい。

hina

unread,
Sep 3, 2012, 6:05:18 AM9/3/12
to android-g...@googlegroups.com
kakajikaさん

情報ありがとうございます。
教えて頂いた方法で動画の再生を停止することができました。
GN 4.0.4で確認。

    @Override
    public void onResume() {
    super.onResume();
mWebView.onResume();     // onResume()しないと再開しない
    }
    
    @Override
    public void onPause() {
    super.onPause();
mWebView.onPause();
    }


こちらはHtml/javascriptに疎く、うまくできていません。
※Androidバージョンによって動作変えたくなく、可能であればこちらで実装したい。
 onShowCustomView()呼びたい。

> アプリ側で解決方法が思いつかないので、
> HTML側を修正して全画面にできないか試してみます。
> 1.HTMLのvideoタグをタッチ
> 2.HTMLでVideoコントールの全画面ボタンと同じイベント発行
> 3.アプリでonShowCustomView()が呼ばれる
ボタンを設けて、全画面にするようにした(つもりの)ソースです。

videoタグ自体を全画面表示しようとしているだけで、
”Videoコントールの全画面ボタンと同じイベント発行 ”ということが分からない状況です。
そもそも可能なのかどうかも含めて、アドバイス頂けたら幸いです。

function movieFullscreen() {
  var v = document.getElementById("video");
  if (v.webkitRequestFullScreen) {
    v.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
  } else if (v.mozRequestFullScreen) {
    v.mozRequestFullScreen();
  } else {
    // ここに処理が入ってきている。
  }
}

<body>
<video id="video" controls="true">
<source src='./test.mp4' type='video/mp4'>
</video>

<input type="button" onClick="movieFullscreen()" value="動画を全画面表示">
</body>

XBG

unread,
Sep 3, 2012, 7:09:23 AM9/3/12
to android-g...@googlegroups.com
Androidでこのページが動くかどうか分かりませんが、
考え得る限りは、このページのコードと同じようにページ側で実装されている必要があるかと。
このページで動かないなら、AndroidのVideoコントロールが全く別のAPIで操作されているということなので我慢するしかないでしょう。

2012年9月3日月曜日 19時05分18秒 UTC+9 hina:

hina

unread,
Sep 3, 2012, 11:23:52 PM9/3/12
to android-g...@googlegroups.com
XBGさん

返信ありがとうございます。

> Androidでこのページが動くかどうか分かりませんが、
> 考え得る限りは、このページのコードと同じようにページ側で実装されている必要があるかと。

GN(4.0.4)で試してみましたが、
標準ブラウザ、WebView共にボタン押しても全画面表示とはなりませんでした。
※elseに入って処理されていませんでした。

  var elem = document.getElementById("video");
if ( elem.requestFullScreen ) {
        elem.requestFullScreen();
    } else if ( elem.webkitRequestFullScreen ) {
        elem.webkitRequestFullScreen();
    } else if ( elem.mozRequestFullScreen ) {
        elem.mozRequestFullScreen();
    } else if ( elem.msRequestFullScreen ) {
        elem.msRequestFullScreen();
    } else if ( elem.oRequestFullScreen ) {
        elem.oRequestFullScreen();
    } else {
    }

無理そうなことが分かりましたので、ひとまず諦めます。
XBGさん、kakajikaさん、ありがとうございました。

kakajika

unread,
Sep 4, 2012, 3:16:14 AM9/4/12
to android-g...@googlegroups.com
hinaさん

kakajikaです。

もう諦めてしまったとのことですが、
一応情報だけ…。

ICSからは、自分でVideoViewを用意する必要があるようで、
onShowCustomView()をオーバーライドして自作のVideoViewを返せば実現できそうな気がします。
僕は試してないのでうまくいくかはわかりません。

hina

unread,
Sep 6, 2012, 10:10:01 PM9/6/12
to android-g...@googlegroups.com
XBGさん、kakajika さん

諦めてたのは、
> アプリ側で解決方法が思いつかないので、
> HTML側を修正して全画面にできないか試してみます。
の方でしたが、解決方法が見つかりました。
myVideo.webkitEnterFullscreen() を呼ぶと、onShowCustomView() が呼ばれる。


<!DOCTYPE html>

<html><head><script> 
var myVideo; 
window.onload = function(){
    myVideo= document.getElementById("myVideoFile"); 
    btnfullMode.addEventListener("click", setFullScreenMode, false); 
function setFullScreenMode() {
    myVideo.webkitEnterFullscreen();
}
</script> </head>
<body> 
<div id="video_container"> 
    <video width="320" height="176" src="./myVideo.mp4" id="myVideoFile" controls /> 
</div><br/> 
<button type="button" id="btnfullMode">
     Open Video in Full Screen mode
</button> 
</body></html>


> ICSからは、自分でVideoViewを用意する必要があるようで、
> onShowCustomView()をオーバーライドして自作のVideoViewを返せば実現できそうな気がします。
onShowCustomView()をオーバーライドしてもAndroid3.x以降では呼ばれないのが、動作変わって困っていた点でした。

ひとまず解決できそうです。
ご助言ありがとうございました。
Reply all
Reply to author
Forward
0 new messages