YouTube 视频未在 WebView 中播放 - Android
Posted
技术标签:
【中文标题】YouTube 视频未在 WebView 中播放 - Android【英文标题】:YouTube Video not playing in WebView - Android 【发布时间】:2012-09-24 09:42:27 【问题描述】:我想在 WebView 中播放 YouTube 视频,WebView 显示带有播放按钮的视频的第一个外观,但是在单击播放按钮后启动进度条并在 2-3 秒后停止进度条并且屏幕空白为黑色。
Image1:带播放按钮的视频优先观看
Image2:点击播放按钮后屏幕变为空白。
请!帮助我为什么视频没有开始。
图像:1
图像:2
这是我在 webview 中播放 YouTubeVideo 的源代码。请帮助我...
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView wv = (WebView) findViewById(R.id.webView1);
wv.getSettings().setjavascriptEnabled(true);
wv.getSettings().setPluginsEnabled(true);
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = getHTML();
wv.loadDataWithBaseURL("", html, mimeType, encoding, "");
public String getHTML()
String html = "<iframe class=\"youtube-player\" style=\"border: 0; width: 100%; height: 95%; padding:0px; margin:0px\" id=\"ytplayer\" type=\"text/html\" src=\"http://www.youtube.com/embed/"
+ "J2fB5XWj6IE"
+ "?fs=0\" frameborder=\"0\">\n"
+ "</iframe>\n";
return html;
【问题讨论】:
所有版本的 android 都会发生这种情况吗?我见过类似的,但只在 4.1 @Nick :Android 3.0、4.0 也有这个问题。 @RanjitChandel 我也有同样的问题... 我还在 AndroidManifest.xml 文件中添加了 android:hardwareAccelerated="true" 。但没有成功。 我遇到了类似的情况。你是怎么做到的? 【参考方案1】:在将 HTML 内容加载到 WebView 之前添加这些行。
wv.setWebChromeClient(new WebChromeClient()
);
来自文档:
为了在您的应用程序中支持内嵌 HTML5 视频,您需要开启硬件加速,并设置 WebChromeClient。对于全屏支持,需要实现 onShowCustomView(View, WebChromeClient.CustomViewCallback) 和 onHideCustomView(),getVideoLoadingProgressView() 是可选的。
【讨论】:
请在这里也给你的cmets***.com/questions/18533678/… 仍然来自文档,关于 onShowCustomView() :此方法在 API 级别 18 中已弃用。此方法支持过时的插件机制,将来不会调用 我试过你的代码,但它在这里不起作用是完整代码gist.github.com/engr-erum/3135924c188f3fe4867270bb7b8b3f0a 不工作。它仍然显示空白屏幕,但正在播放音频。寻求帮助。【参考方案2】:需要以下代码来显示由 web 核心框架启动的视频播放器。整个流程的关键是 VideoView 被传递回 WebChromeClient 并且您需要将该视图附加到您的视图层次结构中。
我通过查看作为 AOSP 的一部分提供的浏览器源代码来组装它。
此代码引用了 4 个可能不明显的视图。视图层次结构是:
FrameLayout mContentView
(根)
WebView mWebView
(mContentView 的子级)
FrameLAyout mCustomViewContainer
(mContentView 的子级)
View mCustomView
(mCustomViewContainer 的子级)
视图被配置为设置容器活动的一部分。
<FrameLayout
android:id="@+id/fullscreen_custom_content"
android:layout_
android:layout_
android:background="#FF000000"/>
<FrameLayout
android:id="@+id/main_content"
android:layout_
android:layout_
android:layout_weight="1" >
<WebView
android:id="@+id/webView"
android:layout_
android:layout_ />
</FrameLayout>
</FrameLayout>
在你的活动中onCreate
:
mContentView = (FrameLayout) findViewById(R.id.main_content);
mWebView = (WebView) findViewById(R.id.webView);
mCustomViewContainer = (FrameLayout) findViewById(R.id.fullscreen_custom_content);
用mWebView
注册WebChromeClient
。该客户端应覆盖以下 2 - 4 个方法:
void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
// if a view already exists then immediately terminate the new one
if (mCustomView != null)
callback.onCustomViewHidden();
return;
// Add the custom view to its container.
mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
mCustomView = view;
mCustomViewCallback = callback;
// hide main browser view
mContentView.setVisibility(View.GONE);
// Finally show the custom view container.
mCustomViewContainer.setVisibility(View.VISIBLE);
mCustomViewContainer.bringToFront();
void onHideCustomView()
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();
// Show the content view.
mContentView.setVisibility(View.VISIBLE);
public Bitmap getDefaultVideoPoster()
if (mDefaultVideoPoster == null)
mDefaultVideoPoster = BitmapFactory.decodeResource(getResources(), R.drawable.default_video_poster);
return mDefaultVideoPoster;
public View getVideoLoadingProgressView()
if (mVideoProgressView == null)
LayoutInflater inflater = LayoutInflater.from(this);
mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
return mVideoProgressView;
您可能还想添加活动生命周期绑定,例如:
@Override
protected void onStop()
super.onStop();
if (mCustomView != null)
if (mCustomViewCallback != null)
mCustomViewCallback.onCustomViewHidden();
mCustomView = null;
@Override
public void onBackPressed()
if (mCustomView != null)
onHideCustomView();
else
finish();
到您的活动以在活动停止或按下后退按钮时隐藏视频。
【讨论】:
能否提供一个干净的代码?有这么多错误?例如mCustomView 在哪里?什么是 COVER_SCREEN_GRAVITY_CENTER? mCustomView 在答案正文中进行了描述。 COVER_SCREEN_GRAVITY_CENTER 是一个 LayoutParameter,其边界设置为 MATCH_PARENT,重力设置为 CENTER。我认为这很明显,抱歉。 @NickCampion 不明白请清除 COVER_SCREEN_GRAVITY_CENTER【参考方案3】:添加webview.setWebChromeClient(new WebChromeClient());
并为您的视频添加插件
if (Build.VERSION.SDK_INT < 8)
webview.getSettings().setPluginsEnabled(true);
else
webview.getSettings().setPluginState(PluginState.ON);
感谢
【讨论】:
是的,这是我缺少的链接。它现在在视频元素中显示 YouTube 播放按钮缩略图。 它对我不起作用。此外, setPluginState(PluginState.ON);已弃用。【参考方案4】:在移动设备上流式传输的 youtbe 视频存在一些问题。如果您直接尝试在 Web 视图中加载 URL 并运行它,则视频将无法播放。解决此问题的一种困难方法是在视频视图中流式传输视频。我没有尝试过,但这可以做到。 播放 youtube 视频的其他方式,我称之为更简单的方式是将网络视图设置中的用户代理从移动设备更改为桌面。用户代理指示将运行 youtube 视频的设备类型,因此服务器会发送该类型的网页。这样,可以流式传输和播放 youtube 视频。执行此操作的方法如下:
public static final int USER_MOBILE = 0;
public static final int USER_DESKTOP = 1;
wv.getSettings().setUserAgent(USER_DESKTOP); // 1 is for the desktop
【讨论】:
将用户代理设置为桌面请求下载 Adobe 插件任何帮助将不胜感激。 WebSettings.setUserAgent(int i) 现在已弃用,也没有解决我的问题。【参考方案5】:我复制了提问者的代码,它对我有用....我想你必须安装 flash payer.. di u??你添加了互联网权限???
顺便说一句,我的代码在这里...
package com.example.youtube;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.util.Log;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebChromeClient;
import android.webkit.WebViewClient;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
public class MainActivity extends Activity
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_main);
final ProgressBar Pbar;
Pbar = (ProgressBar) findViewById(R.id.pB4);
WebView wv = (WebView) findViewById(R.id.webVie1);
//wv.setWebViewClient(new Callback());
WebSettings webSettings = wv.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setJavaScriptEnabled(true);
//wv.setBackgroundColor(0x919191);
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = getHTML();
wv.loadDataWithBaseURL("", html, mimeType, encoding, "");
final Activity activity = this;
wv.setWebChromeClient(new WebChromeClient()
public void onProgressChanged(WebView view, int progress)
// Activities and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach 100%
activity.setProgress(progress * 100);
if(progress < 100 && Pbar.getVisibility() == ProgressBar.GONE)
Pbar.setVisibility(ProgressBar.VISIBLE);
Pbar.setProgress(progress);
if(progress == 100)
Pbar.setVisibility(ProgressBar.GONE);
);
wv.setWebViewClient(new WebViewClient()
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_LONG).show();
);
wv.setDownloadListener(new DownloadListener()
public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype,long contentLength)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
);
private String getHTML()
// TODO Auto-generated method stub
String html1 = "<iframe class=\"youtube-player\" style=\"border: 0; width: 100%; height: 95%; padding:0px; margin:0px\" id=\"ytplayer\" type=\"text/html\" src=\"http://www.youtube.com/embed/"
+ "J2fB5XWj6IE"
+ "?fs=0\" frameborder=\"0\">\n"
+ "</iframe>\n";
return html1;
/* public void onPause()
super.onPause();
System.exit(0);
*/
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<LinearLayout
android:id="@+id/page_buttons"
android:layout_
android:layout_
android:gravity="center_horizontal"
android:orientation="horizontal" >
</LinearLayout>
<WebView
android:id="@+id/webVie1"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_weight="0.99" />
<ProgressBar
android:id="@+id/pB4"
style="?android:attr/progressBarStyleHorizontal"
android:layout_
android:layout_
android:layout_alignParentBottom="true"/> />
</LinearLayout>
【讨论】:
【参考方案6】:以下适用于 Android 10。在您的 Android Activity/Fragment 中加载“WebView”。
检查this 是否有工作项目。
private fun loadVideo(webView: WebView)
val videoUrl = "https://www.youtube.com/embed/5jJ-e278BFY"
val embedString = "<iframe src=\"$videoUrl\" frameborder=\"0\" allowfullscreen></iframe>"
webView.webChromeClient = WebChromeClient()
val webSettings = webView.settings
webSettings.javaScriptEnabled = true
webView.settings.loadWithOverviewMode = true
var text = "<html><body style=\"text-align:justify;\">"
text += embedString
text += "</body></html>"
webView.loadData(text, "text/html", "utf-8")
它使用IFrame Player API。 width (number) -- 视频播放器的宽度。默认值为 640。 height (number) -- 视频播放器的高度。默认值为 390。 videoId (string) - 标识播放器将加载的视频的 YouTube 视频 ID。
下面是 UI xml
<WebView
android:id="@+id/webView"
android:layout_
android:layout_
android:layout_marginTop="40dp"
android:visibility="visible"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/youtubeVideoFrameSubText" />
【讨论】:
【参考方案7】:你为什么要在 webview 中播放你的视频?您可以使用此意图播放它
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(stringUrl)));
如果您想在 webView 中播放,请点击此链接
http://www.***.com/questions/9565533/android-how-to-play-youtube-video-in-webview?rq=1
【讨论】:
【参考方案8】:我的 webview 启用了 javascript,但删除使视频正常工作
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
【讨论】:
【参考方案9】:myWebView.getSettings().setDomStorageEnabled(true);
【讨论】:
【参考方案10】:对我来说,问题是将cleartextTrafficPermitted
设置为false
。出于某种原因,设置此选项不会播放 URL http://www.youtube-nocookie.com/embed/%s
的 YouTube 视频,其中 %s
是 YouTube 视频的 ID。
解决方案是在 network_security_config.xml 文件中包含以下内容。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
</base-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">youtube-nocookie.com</domain>
</domain-config>
</network-security-config>
network_security_config.xml文件在AndroidManifest.xml、<application>
标签和networkSecurityConfig
参数中被引用。
希望这可以节省一些人的时间!
【讨论】:
【参考方案11】:试试这个
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(stringUrl)));
【讨论】:
想在Webview中加载html而不打开外部浏览器窗口以上是关于YouTube 视频未在 WebView 中播放 - Android的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Youtube 视频没有在 webview android 中播放
Flutter WebView 插件无法播放某些 YouTube 视频
音频和视频未在 Android WebView HTML5 中播放
如何在没有 UIWebView 的情况下播放 youtube 视频或在 youtube 视频开始使用 webview 播放时检测视频播放器?