在Android应用程序中集成video文件作为应用程序背景
我需要使用video作为我的背景。 首先我把video文件放在drawable文件夹中,并在main.xml中作为LinearLayout
背景调用。 但是在运行应用程序时,我只看到一个黑屏。 然后我试图使用VideoView
并将其称为如下:
<VideoView android:id="@+id/video" android:layout_width="320px" android:layout_height="240px" android:layout_gravity="center" android:background="@raw/hp"/>
在我的活动文件中,我用下面的代码片段调用它:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); VideoView video=(VideoView) findViewById(R.id.video); video.start(); }
但是我还没有收到video文件。 我的主要build议是使用泡泡video作为背景,并在其上放置两个泡泡button,并给用户一种水景画面的感觉。 谁能帮我?
此外,我想从res文件夹中使用的video文件。 不是从SD卡或任何外部媒体文件夹。
那么我的朋友,首先你不能设置你的VideoView
的背景,并让它在屏幕的背景中播放。
请按照我的步骤,加上你的努力,你应该在那里。
从可绘制的文件夹中删除您的video,并将其添加到原始文件夹。 请谷歌如何创build一个原始文件夹。 这很简单。 把你的video文件放在里面。
首先,像这样在你的xml中创build一个SurfaceView
。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/home_container" android:layout_width="fill_parent" android:layout_height="fill_parent"> <SurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingTop="10dip" /> </Framelayout>
现在,创build一个类如下面的可以实现SurfaceView
,
public class YourMovieActivity extends Activity implements SurfaceHolder.Callback { private MediaPlayer mp = null; //... SurfaceView mSurfaceView=null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mp = new MediaPlayer(); mSurfaceView = (SurfaceView) findViewById(R.id.surface); mSurfaceView.getHolder().addCallback(this); //... } }
现在你的class级会要求添加未实现的方法。 添加这些方法只需点击“添加未实现的方法”
现在你将能够看到像这样的自动生成的方法,
@Override public void surfaceCreated(SurfaceHolder holder) { }
在这个方法里面,添加下面的代码,
@Override public void surfaceCreated(SurfaceHolder holder) { Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.your_raw_file); mp.setDataSource(video); mp.prepare(); //Get the dimensions of the video int videoWidth = mp.getVideoWidth(); int videoHeight = mp.getVideoHeight(); //Get the width of the screen int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); //Get the SurfaceView layout parameters android.view.ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams(); //Set the width of the SurfaceView to the width of the screen lp.width = screenWidth; //Set the height of the SurfaceView to match the aspect ratio of the video //be sure to cast these as floats otherwise the calculation will likely be 0 lp.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth); //Commit the layout parameters mSurfaceView.setLayoutParams(lp); //Start video mp.setDisplay(holder); mp.start(); }
/** * Created by zoid23 on 05/10/15. */ public class IntroVideoSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private static final String TAG = "INTRO_SF_VIDEO_CALLBACK"; private MediaPlayer mp; @TargetApi(Build.VERSION_CODES.LOLLIPOP) public IntroVideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } public IntroVideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public IntroVideoSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public IntroVideoSurfaceView(Context context) { super(context); init(); } private void init (){ mp = new MediaPlayer(); getHolder().addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.intro); try { mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength()); mp.prepare(); } catch (IOException e) { e.printStackTrace(); } int videoWidth = mp.getVideoWidth(); int videoHeight = mp.getVideoHeight(); int screenHeight = getHeight(); android.view.ViewGroup.LayoutParams lp = getLayoutParams(); lp.height = screenHeight; lp.width = (int) (((float)videoWidth / (float)videoHeight) * (float)screenHeight); setLayoutParams(lp); mp.setDisplay(getHolder()); mp.setLooping(true); mp.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mp.stop(); } }
在你的xml中使用IntroVideoSurfaceView并把你的video放入raw/intro.mp4
Luigi23的修改版本的完整版本,避免了一些崩溃。
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
没有主要的活动 。 你可能想要通过添加全屏
<style name="Theme.AppCompat.Light.NoActionBar.FullScreen" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item> </style>
创build一个文件IntroVideoSurfaceView.java
import android.annotation.TargetApi; import android.content.Context; import android.content.res.AssetFileDescriptor; import android.media.MediaPlayer; import android.os.Build; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; import java.io.IOException; public class IntroVideoSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private MediaPlayer mp; private boolean has_started = false; @TargetApi(Build.VERSION_CODES.LOLLIPOP) public IntroVideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } public IntroVideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public IntroVideoSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public IntroVideoSurfaceView(Context context) { super(context); init(); } private void init() { mp = new MediaPlayer(); getHolder().addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.slideshow); try { if (!has_started) { has_started = true; mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength()); } mp.prepare(); android.view.ViewGroup.LayoutParams lp = getLayoutParams(); lp.height = getHeight(); lp.width = getWidth(); setLayoutParams(lp); mp.setDisplay(getHolder()); mp.setLooping(true); mp.start(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mp.stop(); } }
在resources / raw中添加一个“slideshow.mp4”
修改activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/home_container" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.androidadvance.videobackground.IntroVideoSurfaceView android:id="@+id/surface" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Press Me" android:id="@+id/button" android:layout_gravity="center_horizontal|bottom" android:layout_margin="16dp" /> </FrameLayout>
一些笔记。
添加一个video将使你的apk大,所以你可能要避免这一点…不时发生未知的崩溃,即使在高端手机(星系s6),这是必要的,以保持文件小。
我用这个代码在表面视图上播放video
public class VideoPlayOnSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private MediaPlayer mediaPlayer; private boolean has_started = false; @TargetApi(Build.VERSION_CODES.LOLLIPOP) public VideoPlayOnSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } public VideoPlayOnSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public VideoPlayOnSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public VideoPlayOnSurfaceView(Context context) { super(context); init(); } private void init() { mediaPlayer = new MediaPlayer(); getHolder().addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.small); try { if (!has_started) { has_started = true; mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength()); } mediaPlayer.prepare(); android.view.ViewGroup.LayoutParams lp = getLayoutParams(); lp.height = getHeight(); lp.width = getWidth(); setLayoutParams(lp); mediaPlayer.setDisplay(holder); mediaPlayer.setLooping(true); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mediaPlayer.stop(); } }
xml文件
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <YourPacakageName.VideoPlayOnSurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="match_parent" android:paddingTop="10dip" /> </FrameLayout>
我能够得到这个工作与以上和以下其他两个职位的组合:
Android播放器引发exception准备失败:状态0x1
如何在android中将SurfacePlayer与MediaPlayer连接起来?
我用过
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.file_name); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
代替
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.your_raw_file);
并用以下代码设置媒体播放器。
MediaPlayer mp = new MediaPlayer(); SurfaceView mSurfaceView = (SurfaceView) findViewById(R.id.video_surface); SurfaceHolder holder = mSurfaceView.getHolder(); holder.addCallback(this);