WebView và HTML5 <video>


122

Tôi đang kết hợp một ứng dụng rẻ tiền trong số những thứ khác "đóng khung" một số trang web của chúng tôi ... Khá đơn giản với WebViewClient. cho đến khi tôi nhấn video.

Video được thực hiện dưới dạng HTML5 các phần tử và các phần tử này hoạt động tốt và đẹp trên Chrome, iPhone và hiện tại chúng tôi đã khắc phục các sự cố mã hóa, video hoạt động tốt Androidtrong trình duyệt gốc.

Bây giờ chà: WebViewkhông thích nó. Ở tất cả. Tôi có thể nhấp vào hình ảnh áp phích, và không có gì xảy ra.

Googling, tôi thấy điều này gần giống nhưng dường như dựa trên một 'liên kết' (như trong một href ...) thay vì một phần tử video. (onDownloadListener dường như không được gọi trên các phần tử video ...)

Tôi cũng thấy các tham chiếu đến ghi đè onShowCustomView, nhưng điều đó dường như không được gọi trên các phần tử video ... cũng không nênOverrideUrlLoading ..

Tôi không muốn tham gia vào "kéo xml từ máy chủ, định dạng lại nó trong ứng dụng" .. bằng cách giữ bố cục câu chuyện trên máy chủ, tôi có thể kiểm soát nội dung tốt hơn một chút mà không buộc mọi người tiếp tục cập nhật ứng dụng. Vì vậy, nếu tôi có thể thuyết phục WebView xử lý các thẻ giống như trình duyệt gốc, điều đó sẽ là tốt nhất.

Tôi rõ ràng đang thiếu một cái gì đó hiển nhiên .. nhưng tôi không có manh mối gì.



Cùng những dòng này, tôi đang tìm một trình phát HTML5 cho trang web của mình. Tôi nên sử dụng những gì?
Wolfpack'08,

1
Câu trả lời của tôi ở đây: stackoverflow.com/a/16179544/423171
cprcrack

1
Không có gì hoạt động vì vậy tôi đã xem xét VideoEnabledWebViewở đây stackoverflow.com/questions/15768837/…
EpicPandaForce

Câu trả lời:


92

Tôi trả lời chủ đề này chỉ trong trường hợp ai đó đọc nó và quan tâm đến kết quả. Có thể xem phần tử video (thẻ video html5) trong WebView, nhưng tôi phải nói rằng tôi đã phải xử lý nó trong vài ngày. Đây là các bước tôi đã phải làm cho đến nay:

-Tìm video được mã hóa đúng cách

-Khi khởi tạo WebView, hãy đặt JavaScript, Plug-in cho WebViewClient và WebChromeClient.

url = new String ("http://broken-links.com/tests/video/"); 
mWebView = (WebView) findViewById (R.id.webview);
mWebView.setWebChromeClient (chromeClient);
mWebView.setWebViewClient (wvClient);
mWebView.getSettings (). setJavaScriptEnabled (true);
mWebView.getSettings (). setPluginState (PluginState.ON);
mWebView.loadUrl (url);

-Xử lý onShowCustomView trong đối tượng WebChromeClient.

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
    super.onShowCustomView(view, callback);
    if (view instanceof FrameLayout){
        FrameLayout frame = (FrameLayout) view;
        if (frame.getFocusedChild() instanceof VideoView){
            VideoView video = (VideoView) frame.getFocusedChild();
            frame.removeView(video);
            a.setContentView(video);
            video.setOnCompletionListener(this);
            video.setOnErrorListener(this);
            video.start();
        }
    }
}

-Xử lý các sự kiện onCompletion và onError cho video, để quay lại chế độ xem web.

public void onCompletion(MediaPlayer mp) {
    Log.d(TAG, "Video completo");
    a.setContentView(R.layout.main);
    WebView wb = (WebView) a.findViewById(R.id.webview);
    a.initWebView();
}

Nhưng bây giờ tôi nên nói rằng vẫn còn một vấn đề quan trọng. Tôi chỉ có thể chơi nó một lần. Lần thứ hai tôi nhấp vào trình điều phối video (áp phích hoặc một số nút phát), nó không có tác dụng gì.

Tôi cũng muốn video phát bên trong khung WebView, thay vì mở cửa sổ Media Player, nhưng đây là vấn đề phụ đối với tôi.

Tôi hy vọng nó sẽ giúp ai đó, và tôi cũng xin cảm ơn bất kỳ bình luận hoặc đề xuất nào.

Saludos, terrícolas.


Tôi không chạy bất kỳ kết quả nào, màn hình của tôi màu đen. tôi muốn biết nếu cái này cần cái. mã của tôi quá dài để không có ở đây. bạn có thể cho tôi một số cách liên hệ hoặc mở một chủ đề khác.
pengwang

Bạn có hoàn toàn chắc chắn không phải là vấn đề mã hóa? Hãy thử với URL tôi đã đăng. Rõ ràng nó phải làm việc với các trình duyệt bản địa
mdelolmo

46
"a" là gì? như hoạt động đó sẽ là?
Giá Collin

1
@Collin Price a là một ví dụ của Hoạt động lưu trữ webview. @desgraci, tôi có thể cung cấp nó, nhưng không có nhiều thứ ngoài đó. Tạo một lớp mở rộng WebChromeClientvà ghi đè các phương thức tương ứng mà bạn cần. Nếu bạn nhấn mạnh, tôi có thể tải phần còn lại của lớp sau khi tôi về nhà.
mdelolmo

6
Không hoạt động trên ICS vì getFocusedChild () không phải là VideoView mà là HTML5VFullScreen $ SurfaceVideoView. Bất kỳ ý tưởng về cách thực hiện trên ICS? (xem stackoverflow.com/questions/13540654/…
Pascal

61

Sau thời gian dài nghiên cứu, tôi đã làm được điều này. Xem đoạn mã sau:

Test.java

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class Test 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("http://192.168.1.18/xxxxxxxxxxxxxxxx/");
        }

        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();
            //  mWebView.goBack();
                //mWebView.goBack();
                return true;
            }

        }
        return super.onKeyDown(keyCode, event);
    }
}

HTML% VIDEO.java

package com.ivz.idemandtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

public class HTML5WebView extends WebView {

    private Context                             mContext;
    private MyWebChromeClient                   mWebChromeClient;
    private View                                mCustomView;
    private FrameLayout                         mCustomViewContainer;
    private WebChromeClient.CustomViewCallback  mCustomViewCallback;

    private FrameLayout                         mContentView;
    private FrameLayout                         mBrowserFrameLayout;
    private FrameLayout                         mLayout;

    static final String LOGTAG = "HTML5WebView";

    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);

        // 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);
        mWebChromeClient = new MyWebChromeClient();
        setWebChromeClient(mWebChromeClient);

        setWebViewClient(new WebViewClient());

setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

        // 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);
    }

    public HTML5WebView(Context context) {
        super(context);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public FrameLayout getLayout() {
        return mLayout;
    }

    public boolean inCustomView() {
        return (mCustomView != null);
    }

    public void hideCustomView() {
        mWebChromeClient.onHideCustomView();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if ((mCustomView == null) && canGoBack()){
                goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private class MyWebChromeClient extends WebChromeClient {
        private Bitmap      mDefaultVideoPoster;
        private View        mVideoProgressView;

        @Override
        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
        {
            //Log.i(LOGTAG, "here in on ShowCustomView");
            HTML5WebView.this.setVisibility(View.GONE);

            // if a view already exists then immediately terminate the new one
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mCustomViewContainer.addView(view);
            mCustomView = view;
            mCustomViewCallback = callback;
            mCustomViewContainer.setVisibility(View.VISIBLE);
        }

        @Override
        public void onHideCustomView() {
            System.out.println("customview hideeeeeeeeeeeeeeeeeeeeeeeeeee");
            if (mCustomView == null)
                return;        

            // Hide the custom view.
            mCustomView.setVisibility(View.GONE);

            // Remove the custom view from its container.
            mCustomViewContainer.removeView(mCustomView);
            mCustomView = null;
            mCustomViewContainer.setVisibility(View.GONE);
            mCustomViewCallback.onCustomViewHidden();

            HTML5WebView.this.setVisibility(View.VISIBLE);
            HTML5WebView.this.goBack();
            //Log.i(LOGTAG, "set it to webVew");
        }


        @Override
        public View getVideoLoadingProgressView() {
            //Log.i(LOGTAG, "here in on getVideoLoadingPregressView");

            if (mVideoProgressView == null) {
                LayoutInflater inflater = LayoutInflater.from(mContext);
                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
            }
            return mVideoProgressView; 
        }

         @Override
         public void onReceivedTitle(WebView view, String title) {
            ((Activity) mContext).setTitle(title);
         }

         @Override
         public void onProgressChanged(WebView view, int newProgress) {
             ((Activity) mContext).getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress*100);
         }

         @Override
         public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
             callback.invoke(origin, true, false);
         }
    }


    static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
        new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

custom_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
    <FrameLayout android:id="@+id/fullscreen_custom_content"
        android:visibility="gone"
        android:background="@color/black"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    />
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:id="@+id/error_console"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
        />

        <FrameLayout android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />
    </LinearLayout>
</FrameLayout>

video_loading_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/progress_indicator"
         android:orientation="vertical"
         android:layout_centerInParent="true"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">

       <ProgressBar android:id="@android:id/progress"
           style="?android:attr/progressBarStyleLarge"
           android:layout_gravity="center"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" />

       <TextView android:paddingTop="5dip"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center"
           android:text="@string/loading_video" android:textSize="14sp"
           android:textColor="?android:attr/textColorPrimary" />
 </LinearLayout>

color.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/http_authentication_colors.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->
<!-- FIXME: Change the name of this file!  It is now being used generically
    for the browser -->
<resources>
    <color name="username_text">#ffffffff</color>
    <color name="username_edit">#ff000000</color>

    <color name="password_text">#ffffffff</color>
    <color name="password_edit">#ff000000</color>

    <color name="ssl_text_label">#ffffffff</color>
    <color name="ssl_text_value">#ffffffff</color>

    <color name="white">#ffffffff</color>
    <color name="black">#ff000000</color>



    <color name="geolocation_permissions_prompt_background">#ffdddddd</color>
</resources>

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Test"
                  android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:configChanges="orientation|keyboardHidden|keyboard">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>  
<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" />
</manifest>

Mong đợi những điều còn lại bạn có thể hiểu.


7
Đây là câu trả lời được chấp nhận. Cả Surendra và Malenkiy, bạn đều đã cứu tôi. Làm việc rất tốt cho tôi.
George Baker

Tôi đồng ý với George. Đây chính xác là cách trình duyệt gốc Android hoạt động với VideoView. Có vẻ như đây là mã giống như ở đây code.google.com/p/html5webview . Nó hoạt động tốt cho tất cả các phiên bản Android (tôi đã thử nghiệm trên Android 2.2 trở lên). Chỉ có một điều tôi muốn lưu ý, bạn nên nhớ rằng nếu bạn thay đổi SDK mục tiêu trên thứ gì đó trên 13 thì hoạt động của bạn sẽ được tạo lại khi thay đổi hướng. Để tránh điều này, hoặc append screensize để android: configChanges (nhưng trong trường hợp này, bạn sẽ cần sử dụng min sdk <13) hoặc sử dụng cũ mục tiêu SDK (sau đó bạn có thể giữ android: configChanges)
Yuriy Ashaev

2
Điều này khiến tôi có một màn hình trống màu trắng trên nexus 7 (android 4.1). Bất kỳ ý tưởng làm thế nào để sửa chữa điều này?
Sahil

Nút bấm không dừng video và âm thanh vẫn nghe được, bạn có biết cách khắc phục điều này không?
CONvid 19

Đây là những gì tôi đang tìm kiếm giống hệt như luồng trình duyệt gốc .. Cảm ơn Ton Surendra và Malenkiy.
Abhilash

33

Câu trả lời của mdelolmo vô cùng hữu ích, nhưng như anh ấy đã nói, video chỉ phát một lần và sau đó bạn không thể mở lại.

Tôi đã xem xét vấn đề này một chút và đây là những gì tôi tìm thấy, trong trường hợp bất kỳ khách du lịch WebView nào mệt mỏi như tôi gặp phải bài đăng này trong tương lai.

Trước hết, tôi đã xem tài liệu của VideoViewMediaPlayer và hiểu rõ hơn về cách chúng hoạt động. Tôi thực sự khuyên bạn nên những.

Sau đó, tôi xem mã nguồn để xem Trình duyệt Android thực hiện nó như thế nào . Tìm trang và xem cách họ xử lý onShowCustomView(). Họ giữ một tham chiếu đến CustomViewCallbackvà đến chế độ xem tùy chỉnh.

Với tất cả những điều đó và với câu trả lời của mdelolmo, khi bạn xem xong video, tất cả những gì bạn cần làm là hai việc. Đầu tiên, trên cái VideoViewmà bạn đã lưu một tham chiếu, hãy gọi stopPlayback()nó sẽ giải phóng tham chiếu sẽ MediaPlayerđược sử dụng sau đó ở nơi khác. Bạn có thể thấy nó trong mã nguồn VideoView . Thứ hai, CustomViewCallbackbạn đã lưu một tham chiếu để gọi CustomViewCallback.onCustomViewHidden().

Sau khi thực hiện hai điều đó, bạn có thể nhấp vào cùng một video hoặc bất kỳ video nào khác và nó sẽ mở ra như trước. Không cần khởi động lại toàn bộ WebView.

Hy vọng rằng sẽ giúp.


Thực ra thì tôi cũng đã giải được rồi, chỉ là tôi không nhớ đã đăng giải pháp (xấu hổ cho tôi). Cũng giống như bạn, tôi đã phải xem mã của trình duyệt Android và tốt, không cần phải thêm nhiều, tôi đã sử dụng trình nghe onCompletion để dừng Trình phát thay thế và phải đặt chế độ hiển thị một vài lần, nhưng tôi sẽ mua giải pháp của bạn. Trân trọng!
mdelolmo

1
Google Code Search đã nghỉ hưu, tôi nghĩ rằng phiên bản này của BrowserActivity.java (từ Froyo) xấp xỉ tương ứng với một trong những mô tả ở đây: github.com/android/platform_packages_apps_browser/blob/...
michiakig

Mã được liên kết của @ spacemanki không chứa bất kỳ đề cập nào về VideoView trong toàn bộ repo. Tôi đoán BrowserActivity hiện làm việc đó theo cách khác. Tôi thậm chí đã quay lại bản phát hành Eclair. Không thể tìm thấy bất kỳ cách sử dụng nào.
mxcl

Vấn đề tôi gặp phải với tất cả những điều này là những gì tôi đang nhận lại từ frame.getFocusedChild (); là HTml5VideoView thay vì ViewView và do đó không cái nào trong số này phù hợp với tôi và không thể chuyển sang chế độ toàn màn hình :( Tôi đang sử dụng Android 4.1.2.
Gonan

1
Điều cuối cùng đã làm cho tôi là thêm: @Override public void onStop () {super.onStop (); mWebView.destroy (); } đối với hoạt động ... webview.destroy () là rất quan trọng
MacD

8

Trên thực tế, chỉ cần đính kèm một WebChromeClient có sẵn vào chế độ xem khách hàng là đủ, ala

mWebView.setWebChromeClient(new WebChromeClient());

và bạn cần phải bật tăng tốc phần cứng!

Ít nhất, nếu bạn không cần phát video toàn màn hình, thì không cần phải kéo VideoView ra khỏi WebView và đẩy nó vào chế độ xem Hoạt động. Nó sẽ phát trong trực tràng được phân bổ của phần tử video.

Bất kỳ ý tưởng làm thế nào để chặn nút video mở rộng?


bạn có thể chặn nó bằng cách sử dụng WebChromeClient và ghi đè onShowCustomView
Frank

Vui lòng chỉ định phiên bản Android nào. Điều này hoạt động khác nhau cho các phiên bản khác nhau.
Ethan_AI

7

Tôi biết chuỗi này đã được vài tháng, nhưng tôi đã tìm thấy giải pháp để phát video bên trong WebView mà không làm nó ở chế độ toàn màn hình (nhưng vẫn trong trình phát phương tiện ...). Cho đến nay, tôi không tìm thấy bất kỳ gợi ý nào về điều này trên internet nên có lẽ điều này cũng thú vị với những người khác. Tôi vẫn đang gặp khó khăn về một số vấn đề (tức là đặt trình phát media ở phần bên phải của màn hình, không biết tại sao tôi lại làm sai nhưng tôi nghĩ đó là một vấn đề tương đối nhỏ ...).

Trong ChromeClient tùy chỉnh, chỉ định LayoutParams:

// 768x512 is the size of my video
FrameLayout.LayoutParams LayoutParameters = 
                                     new FrameLayout.LayoutParams (768, 512); 

Phương thức onShowCustomView của tôi trông như thế này:

public void onShowCustomView(final View view, final CustomViewCallback callback) {
     // super.onShowCustomView(view, callback);
     if (view instanceof FrameLayout) {
         this.mCustomViewContainer = (FrameLayout) view;
         this.mCustomViewCallback = callback;
         this.mContentView = (WebView) this.kameha.findViewById(R.id.webview);
         if (this.mCustomViewContainer.getFocusedChild() instanceof VideoView) {
             this.mCustomVideoView = (VideoView) 
                                     this.mCustomViewContainer.getFocusedChild();
             this.mCustomViewContainer.setVisibility(View.VISIBLE);
             final int viewWidth = this.mContentView.getWidth();
             final int viewLeft = (viewWidth - 1024) / 2;
             // get the x-position for the video (I'm porting an iPad-Webapp to Xoom, 
             // so I can use those numbers... you have to find your own of course...
             this.LayoutParameters.leftMargin = viewLeft + 256; 
             this.LayoutParameters.topMargin = 128;
             // just add this view so the webview underneath will still be visible, 
             // but apply the LayoutParameters specified above
             this.kameha.addContentView(this.mCustomViewContainer, 
                                             this.LayoutParameters); 
             this.mCustomVideoView.setOnCompletionListener(this);
             this.mCustomVideoView.setOnErrorListener(this);
             // handle clicks on the screen (turning off the video) so you can still
             // navigate in your WebView without having the video lying over it
             this.mCustomVideoView.setOnFocusChangeListener(this); 
             this.mCustomVideoView.start();
         }
     }
 }

Vì vậy, tôi hy vọng tôi có thể giúp đỡ ... Tôi cũng đã phải tìm hiểu về Mã hóa video và thấy các loại khác nhau của việc sử dụng WebView với video html5 - cuối cùng thì mã làm việc của tôi là một hỗn hợp hoang dã của các phần mã khác nhau mà tôi tìm thấy trong Internet và một số thứ tôi phải tự tìm hiểu. Nó thực sự là một nỗi đau trong một *.


Trên ICS, getFocusedChild () không trả về VideoView. Bất kỳ ý tưởng về cách làm cho điều này hoạt động trên ICS?
Pascal

4

Cách tiếp cận này hoạt động rất tốt cho đến 2.3 Và bằng cách thêm phần cứngaccelerated = true, nó thậm chí hoạt động từ 3.0 đến ICS Một vấn đề tôi đang gặp phải hiện tại là khi khởi chạy lần thứ hai ứng dụng trình phát đa phương tiện đang gặp sự cố vì tôi chưa ngừng phát lại và phát hành Trình phát phương tiện. Là đối tượng VideoSurfaceView, mà chúng tôi nhận được trong chức năng onShowCustomView từ Hệ điều hành 3.0, dành riêng cho trình duyệt chứ không phải đối tượng VideoView như trong Hệ điều hành 2.3 Làm cách nào để truy cập nó và dừng Phát lại và giải phóng tài nguyên?


3

AM's tương tự như BrowerActivity làm. cho FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams (768, 512);

Tôi nghĩ chúng ta có thể sử dụng

FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
            FrameLayout.LayoutParams.FILL_PARENT) 

thay thế.

Một vấn đề khác tôi đã gặp là nếu video đang phát và người dùng nhấp vào nút quay lại, lần sau, bạn chuyển đến hoạt động này (singleTop một) và không thể phát video. để khắc phục điều này, tôi đã gọi

try { 
    mCustomVideoView.stopPlayback();  
    mCustomViewCallback.onCustomViewHidden();
} catch(Throwable e) { //ignore }

trong phương thức onBackPressed của hoạt động.


2

Tôi biết đây là một câu hỏi rất cũ, nhưng bạn đã thử hardwareAccelerated="true"cờ tệp kê khai cho ứng dụng hoặc hoạt động của mình chưa?

Với bộ này, nó dường như hoạt động mà không cần bất kỳ sửa đổi WebChromeClient nào (điều mà tôi mong đợi từ Phần tử DOM).


2
hardwareAcceleratedbắt đầu từ Android 3.0
vbence

2

Tôi đã sử dụng html5webview để giải quyết vấn đề này. Tải xuống và đưa nó vào dự án của bạn sau đó bạn có thể viết mã như thế này.

private HTML5WebView mWebView;
String url = "SOMEURL";
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mWebView = new HTML5WebView(this);
    if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
    } else {
            mWebView.loadUrl(url);
    }
    setContentView(mWebView.getLayout());
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mWebView.saveState(outState);
}

Để video có thể xoay được, hãy đặt mã android: configChanges = "direction" vào Hoạt động của bạn chẳng hạn (Androidmanifest.xml)

<activity android:name=".ui.HTML5Activity" android:configChanges="orientation"/>

và ghi đè phương thức onConfigurationChanged.

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
}

2

Câu hỏi này đã cũ, nhưng có lẽ câu trả lời của tôi sẽ giúp những người như tôi, những người phải hỗ trợ phiên bản Android cũ. Tôi đã thử rất nhiều cách tiếp cận khác nhau hoạt động trên một số phiên bản Android, nhưng không phải tất cả. Giải pháp tốt nhất mà tôi tìm thấy là sử dụng Crosswalk Webview được tối ưu hóa để hỗ trợ tính năng HTML5 và hoạt động trên Android 4.1 trở lên. Nó đơn giản để sử dụng như WebView mặc định của Android. Bạn chỉ cần bao gồm thư viện. Tại đây bạn có thể tìm thấy một hướng dẫn đơn giản về cách sử dụng nó: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/


Lưu ý: Lối đi bộ qua đường không được duy trì nữa.
slhck

1

Vâng, rõ ràng điều này là không thể thực hiện được nếu không sử dụng JNI để đăng ký một plugin để tải sự kiện video. (Cá nhân tôi đang tránh JNI vì tôi thực sự không muốn đối phó với một mớ hỗn độn khi máy tính bảng Android dựa trên Atom ra mắt trong vài tháng tới, làm mất tính di động của Java.)

Cách thay thế thực sự duy nhất dường như là tạo một trang web mới chỉ dành cho WebView và quay video theo cách cũ với một liên kết A HREF như được trích dẫn trong url Codelark ở trên.

Chán.


1

Sử dụng tổ ong hardwareaccelerated=truepluginstate.on_demandcó vẻ hoạt động


1

Tôi đã có một vấn đề tương tự. Tôi có các tệp và video HTML trong thư mục nội dung của ứng dụng của mình.

Do đó, các video được đặt bên trong APK. Vì APK thực sự là một tệp ZIP, WebView không thể đọc các tệp video.

Việc sao chép tất cả các tệp HTML và video vào SD-Card phù hợp với tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.