Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在亚马逊Fire TV的WebView中播放YouTube视频?_Android_Video_Webview_Youtube_Amazon Fire Tv - Fatal编程技术网

Android 如何在亚马逊Fire TV的WebView中播放YouTube视频?

Android 如何在亚马逊Fire TV的WebView中播放YouTube视频?,android,video,webview,youtube,amazon-fire-tv,Android,Video,Webview,Youtube,Amazon Fire Tv,我想在亚马逊Fire TV的网络视图中播放YouTube视频 到今天为止,FireOS()上还没有用于播放YouTube视频的官方API,所以我尝试让它与Android的WebView配合使用。在文档中写道,应用程序需要打开硬件加速,WebView需要有WebChromeClient才能播放YouTube视频 我试图让它工作,但当我开始一个YouTube视频,我只看到在全屏模式加载微调器 这是我的密码: @Override public void onCreate(Bundle savedIns

我想在亚马逊Fire TV的网络视图中播放YouTube视频

到今天为止,FireOS()上还没有用于播放YouTube视频的官方API,所以我尝试让它与Android的WebView配合使用。在文档中写道,应用程序需要打开硬件加速,WebView需要有WebChromeClient才能播放YouTube视频

我试图让它工作,但当我开始一个YouTube视频,我只看到在全屏模式加载微调器

这是我的密码:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  WebView webview = new WebView(this);
  setContentView(webview);

  webview.getSettings().setBuiltInZoomControls(true);
  webview.getSettings().setJavaScriptEnabled(true);
  webview.setWebChromeClient(new WebChromeClient() {

    @Override
    public void onShowCustomView(View view, CustomViewCallback callback) {
      Log.i("fire-tv", "Show custom view");

      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);
          setContentView(video);
          video.start();
        }
      }
    }

    @Override
    public void onHideCustomView() {
      Log.i("fire-tv", "Hide custom view.");
    }

  });

  webview.setWebViewClient(new WebViewClient() {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      return false;
    }

  });

  final String mimeType = "text/html";
  final String encoding = "UTF-8";
  String html = getHTML();

  Log.i("fire-tv", "Loading: " + html);
  webview.loadDataWithBaseURL("", html, mimeType, encoding, "");
}

private String getHTML() {
  String html = "<iframe class=\"youtube-player\" style=\"border: 0; width: 100%; height: 100%; padding:0px; margin:0px\" id=\"ytplayer\" type=\"text/html\" src=\"http://www.youtube.com/embed/"
          + "h11u3vtcpaY"
          + "?fs=0\" frameborder=\"0\">\n"
          + "</iframe>\n";

  return html;
}
@覆盖
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
WebView WebView=新的WebView(此);
setContentView(网络视图);
webview.getSettings().setBuilTinZoomControl(true);
webview.getSettings().setJavaScriptEnabled(true);
setWebView.WebChromeClient(新WebChromeClient(){
@凌驾
ShowCustomView(视图视图、CustomViewCallback回调)上的公共无效{
Log.i(“消防电视”、“显示自定义视图”);
super.onShowCustomView(查看、回调);
if(查看FrameLayout的实例){
FrameLayout frame=(FrameLayout)视图;
if(视频视图的frame.getFocusedChild()实例){
VideoView视频=(VideoView)frame.getFocusedChild();
frame.removeView(视频);
setContentView(视频);
video.start();
}
}
}
@凌驾
公共无效onHideCustomView(){
Log.i(“消防电视”,“隐藏自定义视图”);
}
});
setWebViewClient(新的WebViewClient(){
@凌驾
公共布尔值shouldOverrideUrlLoading(WebView视图,字符串url){
返回false;
}
});
最终字符串mimeType=“text/html”;
最终字符串编码=“UTF-8”;
字符串html=getHTML();
Log.i(“消防电视”,“加载:+html”);
loadDataWithBaseURL(“,html,mimeType,encoding,”);
}
私有字符串getHTML(){
字符串html=“\n”
+“\n”;
返回html;
}

我编写了一个在Fire TV上播放youtube视频的类,它也可以在kindle Fire上播放。正如你所知,Youtube没有一个官方的api,我们不得不求助于使用网络视图。我在这里粘贴的类除了网络视图之外还有很多东西,你可能会好奇,所以我会解释。首先,你会发现当你离开你的活动时,一个YouTube播放的webview会继续播放,除非你告诉它停止。因此,人们告诉其他人的解决方案是使用onPause和pauseTimers方法来关闭视频。但亚马逊强加给我们的一个棘手问题是,音频和视频资源没有发布到操作系统的其他部分(谷歌Android Lolipop ie Nexus Player没有问题)。当资源由你的应用程序持有时,prime video将不会播放,亚马逊也不会允许你的应用程序出现在商店中。他们很清楚我们必须使用youtube的网络视图,所以他们给了我们一些建议:

问:我可以在视频中使用Android WebView和HTML标记吗 播放?
A:是的,有限制。硬件媒体资源不可用 当前由系统在应用程序暂停或停止时发布。到 解决这个问题实现onStop()方法以显式 终止应用程序的进程:

就像AVGN会说“他们在想什么?”

你不会相信仅仅是强制终止一个应用程序或活动会导致成吨的问题。。我相信你会的,因为你比我多了几千分

我能找到的唯一解决方案是在onPause方法中加载一个非常短的720p高清剪辑(必须有音频!)。我将它与webView.onPause和.pauseTimers相结合,以确保

如果您使用这个类,请将我的blank.mp4文件复制到您自己的服务器,因为它可能在一个月内不存在

哦,但还有更多。所以你在你的网络视图中得到你的YouTube文件。。。小菜一碟,对吗?错了,它不会播放,因为在网络视图中,Html5通常不会自动播放。您不能将url设置为自动播放,这没有任何区别。因此,我的解决方案是使用java技巧强制单击。它的工作方式是webview不会立即加载,完全加载需要不同的时间。完成后,视频会在屏幕中央显示播放按钮图标。由于某种原因,这个小遥控器碰不到它。但是我输入了代码来强制点击webview的中心

哦,还有一件事,你必须处理音频焦点,否则亚马逊将不允许你的应用在商店里。潘多拉可以在后台播放,除非你处理好了

为什么亚马逊为什么

package com.ohiovr.modules.youtube;


import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.Timer;
import java.util.TimerTask;



public class youtubeKindleWebView extends Activity {


    String StringYoutubeUrl;
    WebView webView;

    AFChangeListener hocusFocus;
    private String videoBlanker = "http://ohiovr.com/church_files/blank.mp4";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_generic_web_view);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        webView = (WebView) findViewById(R.id.webView);
        WebSettings webSettings = webView.getSettings();
        webSettings.setBuiltInZoomControls(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setAppCacheEnabled(false);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(true);
        //I used this line in an old and now not used live stream implimentation. It works so I didn't remove it. But you may 
        //want to see if it is nessisary:
        webSettings.setUserAgentString("Mozilla/5.0(iPhone;U;CPUiPhoneOS4_0likeMacOSX;en-us)AppleWebKit/532.9(KHTML,likeGecko)Version/4.0.5Mobile/8A293Safari/6531.22.7");


        webView.setWebViewClient(new Callback()); 
        webView.setWebChromeClient(new WebChromeClient());


    }

    class AFChangeListener implements AudioManager.OnAudioFocusChangeListener {
        @Override
        public void onAudioFocusChange(int focusChange) {
            if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
                // mp.pause();
            } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                //  mp.start();
            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
                //  mp.stop();
            }
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        boolean handled = false;

        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
                forceAClick();
                break;
            case KeyEvent.KEYCODE_BUTTON_A:
                // ... handle selections
                handled = true;
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                // ... handle left action
                handled = true;
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                // ... handle right action
                handled = true;
                break;
        }
        return handled || super.onKeyDown(keyCode, event);
    }


    public void forceAClick() {

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Display display = getWindowManager().getDefaultDisplay();
                        Point size = new Point();
                        display.getSize(size);
                        int width = size.x;
                        int height = size.y;


                        // Obtain MotionEvent object
                        long downTime = SystemClock.uptimeMillis();
                        long eventTime = SystemClock.uptimeMillis() + 100;
                        float x = width / 2;
                        float y = height / 2;
                        // List of meta states found here: developer.android.com/reference/android/view/KeyEvent.html#getMetaState()
                        int metaState = 0;
                        MotionEvent motionEvent = MotionEvent.obtain(
                                downTime,
                                eventTime,
                                MotionEvent.ACTION_DOWN,
                                x,
                                y,
                                metaState
                        );

                        webView.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                Log.d("on touch", "touched down");
                                return false;
                            }
                        });

                        webView.dispatchTouchEvent(motionEvent);
                    }
                });
            }
        }, 1);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Display display = getWindowManager().getDefaultDisplay();
                        Point size = new Point();
                        display.getSize(size);
                        int width = size.x;
                        int height = size.y;


                        // Obtain MotionEvent object
                        long downTime = SystemClock.uptimeMillis();
                        long eventTime = SystemClock.uptimeMillis() + 100;
                        float x = width / 2;
                        float y = height / 2;
                        // List of meta states found here: developer.android.com/reference/android/view/KeyEvent.html#getMetaState()
                        int metaState = 0;
                        MotionEvent motionEvent = MotionEvent.obtain(
                                downTime,
                                eventTime,
                                MotionEvent.ACTION_UP,
                                x,
                                y,
                                metaState
                        );

                        webView.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                Log.d("on touch", "touched up");
                                return false;
                            }
                        });

                        webView.dispatchTouchEvent(motionEvent);


                    }
                });
            }
        }, 120);


        AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
// Request audio focus for playback
        hocusFocus = new AFChangeListener();
        int result = am.requestAudioFocus(hocusFocus, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
    }


    @Override
    public void onResume() {
        super.onResume();
        webView.onResume();
        webView.resumeTimers();
        StringYoutubeUrl = "https://www.youtube.com/embed/" + getIntent().getStringExtra("youtubeID");
        webView.loadUrl(StringYoutubeUrl);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    }


    private class Callback extends WebViewClient {  //this is important for some reason. don't remove!
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return (false);
        }
    }


    @Override
    protected void onPause() {
        super.onPause();

        webView.loadUrl(videoBlanker);
        webView.pauseTimers();
        webView.onPause();
    }



    /*
    Q: Can I use an Android WebView and the <video> HTML tag for video playback?
    A:
    Yes, with limitations. Hardware media resources are not currently released by the system when your app pauses or stops. To work around this issue implement your onStop() method to explicitly kill the process for your app:

    https://developer.amazon.com/public/solutions/devices/fire-tv/docs/amazon-fire-tv-sdk-frequently-asked-questions
    public void onStop() {
        super.onStop();
        android.os.Process.killProcess(android.os.Process.myPid());
    }
    This issue may also cause instability in the user experience and navigation for your app. The VisualOn SDK is the recommended method for media playback on the device.
    */

    @Override
    protected void onStop() {
        super.onStop();
        // the fascinating part of the next line is that it doesn't kill the application, only this intent
        /////////////  android.os.Process.killProcess(android.os.Process.myPid());
        //no no no! Amazon's advice is bad. It causes a ton of problems.
        //the original problem was that the webview video view frankenhybrid wouldn't release the
        //hardware when the user left the video player.
        //the only and correct solution is to load a very short quiet clip into the webview
        //when the user leaves
        //see onPause for my implementation

    }


}
package com.ohiovr.modules.youtube;
导入android.app.Activity;
导入android.content.Context;
导入android.content.pm.ActivityInfo;
导入android.graphics.Point;
导入android.media.AudioManager;
导入android.os.Bundle;
导入android.os.SystemClock;
导入android.util.Log;
导入android.view.Display;
导入android.view.KeyEvent;
导入android.view.MotionEvent;
导入android.view.view;
导入android.view.WindowManager;
导入android.webkit.WebChromeClient;
导入android.webkit.WebSettings;
导入android.webkit.WebView;
导入android.webkit.WebViewClient;
导入java.util.Timer;
导入java.util.TimerTask;
公共类youtubeKindleWebView扩展活动{
弦乐;
网络视图;
AFC聚焦;
专用字符串videoBlanker=”http://ohiovr.com/church_files/blank.mp4";
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u generic\u web\u视图);
setRequestedOrientation(ActivityInfo.SCREEN\u ORIENTATION\u横向);
webView=(webView)findviewbyd(R.id.webView);
WebSettings WebSettings=webView.getSettings();
webSettings.SetBuilTinZoomControl(真);
setJavaScriptEnabled(true);
织网