web-dev-qa-db-ja.com

ビデオをストレッチせずに全画面ビデオビュー

フルスクリーンでビデオビューを介してビデオを実行する方法を得ることができるのだろうか?

私はよく検索して、次のような多くの方法を試しました。

  1. マニフェストにテーマを適用します。

    Android:theme="@Android:style/Theme.NoTitleBar.Fullscreen"
    

    しかし、それはビデオをフルスクリーンにすることを強制しません。

  2. アクティビティ自体に適用:

    requestWindowFeature(Window.FEATURE_NO_TITLE);  
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
    

    また、ビデオを強制的にフルスクリーンにしません。

ビデオをフルスクリーンにする唯一の方法は次のとおりです。

<VideoView Android:id="@+id/myvideoview"
    Android:layout_width="fill_parent"
    Android:layout_alignParentRight="true"
    Android:layout_alignParentLeft="true" 
    Android:layout_alignParentTop="true" 
    Android:layout_alignParentBottom="true" 
    Android:layout_height="fill_parent"> 
</VideoView> 

この方法では、フルスクリーンのビデオになりますが、ビデオ自体を引き伸ばします(細長いビデオ)、

この不適切なソリューションをビデオビューに適用していないので、ビデオをストレッチせずにそれを行う方法はありますか?

ビデオクラス:

public class Video extends Activity {
    private VideoView myvid;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        myvid = (VideoView) findViewById(R.id.myvideoview);
        myvid.setVideoURI(Uri.parse("Android.resource://" + getPackageName() 
            +"/"+R.raw.video_1));
        myvid.setMediaController(new MediaController(this));
        myvid.requestFocus();
        myvid.start();
    }
}

main.xml:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:orientation="vertical" >

    <VideoView
        Android:id="@+id/myvideoview"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent" />

</LinearLayout>
28
Android Stack

このように、ビデオのプロパティを自分で設定できます。

SurfaceViewを使用して(ビューをより詳細に制御できます)、fill_parentに設定して画面全体に一致させます

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"     
              Android:orientation="vertical" 
              Android:layout_width="match_parent"
              Android:layout_height="fill_parent">

    <SurfaceView
        Android:id="@+id/surfaceViewFrame"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:layout_gravity="center" >
    </SurfaceView>
</Linearlayout>

次に、Javaコードで表面ビューを取得し、メディアプレーヤーを追加します

surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
player = new MediaPlayer();
player.setDisplay(holder);

メディアプレーヤーにonPreparedListenerを設定し、ビデオのストレッチを回避するために希望する比率で画面を満たすために、ビデオの希望するサイズを手動で計算します!

player.setOnPreparedListener(new OnPreparedListener() {

        @Override
        public void onPrepared(MediaPlayer mp) {
                    // Adjust the size of the video
    // so it fits on the screen
    int videoWidth = player.getVideoWidth();
    int videoHeight = player.getVideoHeight();
    float videoProportion = (float) videoWidth / (float) videoHeight;       
    int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
    float screenProportion = (float) screenWidth / (float) screenHeight;
    Android.view.ViewGroup.LayoutParams lp = surfaceViewFrame.getLayoutParams();

    if (videoProportion > screenProportion) {
        lp.width = screenWidth;
        lp.height = (int) ((float) screenWidth / videoProportion);
    } else {
        lp.width = (int) (videoProportion * (float) screenHeight);
        lp.height = screenHeight;
    }
    surfaceViewFrame.setLayoutParams(lp);

    if (!player.isPlaying()) {
        player.start();         
    }

        }
    });

少し前に行ったビデオストリーミングのチュートリアルからこれを変更しましたが、参照するために今すぐ見つけることができません。誰かが答えにリンクを追加してください!

それが役に立てば幸い!

[〜#〜] edit [〜#〜]

それでは、ビデオを画面全体に表示したいのに、拡大したくない場合は、横に黒い縞ができてしまいます。私が投稿したコードでは、ビデオまたは電話の画面の大きいほうを見つけて、できる限り最適な方法に合わせています。

リンクからビデオをストリーミングする私の完全なアクティビティがあります。 100%機能的です。自分のデバイスからビデオを再生する方法はわかりません。ドキュメンテーション here または here で見つかるはずです。

public class VideoPlayer extends Activity implements Callback, OnPreparedListener, OnCompletionListener, 
    OnClickListener {   

private SurfaceView surfaceViewFrame;
private static final String TAG = "VideoPlayer";
private SurfaceHolder holder;
private ProgressBar progressBarWait;
private ImageView pause;
private MediaPlayer player; 
private Timer updateTimer;
String video_uri = "http://daily3gp.com/vids/familyguy_has_own_orbit.3gp";  


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.videosample);       


    pause = (ImageView) findViewById(R.id.imageViewPauseIndicator);
    pause.setVisibility(View.GONE);
    if (player != null) {
        if (!player.isPlaying()) {
            pause.setVisibility(View.VISIBLE);
        }
    }


    surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
    surfaceViewFrame.setOnClickListener(this);
    surfaceViewFrame.setClickable(false);

    progressBarWait = (ProgressBar) findViewById(R.id.progressBarWait);

    holder = surfaceViewFrame.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_Push_BUFFERS);

    player = new MediaPlayer();
    player.setOnPreparedListener(this);
    player.setOnCompletionListener(this);
    player.setScreenOnWhilePlaying(true);
    player.setDisplay(holder);
}

private void playVideo() {
        new Thread(new Runnable() {
            public void run() {
                try {
                    player.setDataSource(video_uri);
                    player.prepare();
                } catch (Exception e) { // I can split the exceptions to get which error i need.
                    showToast("Error while playing video");
                    Log.i(TAG, "Error");
                    e.printStackTrace();
                } 
            }
        }).start();     
}

private void showToast(final String string) {
    runOnUiThread(new Runnable() {
        public void run() {
            Toast.makeText(VideoPlayer.this, string, Toast.LENGTH_LONG).show();
            finish();
        }
    });
}


public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub

}

public void surfaceCreated(SurfaceHolder holder) {
    playVideo();
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub

}
//prepare the video
public void onPrepared(MediaPlayer mp) {        
    progressBarWait.setVisibility(View.GONE);

    // Adjust the size of the video
    // so it fits on the screen
    int videoWidth = player.getVideoWidth();
    int videoHeight = player.getVideoHeight();
    float videoProportion = (float) videoWidth / (float) videoHeight;       
    int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
    float screenProportion = (float) screenWidth / (float) screenHeight;
    Android.view.ViewGroup.LayoutParams lp = surfaceViewFrame.getLayoutParams();

    if (videoProportion > screenProportion) {
        lp.width = screenWidth;
        lp.height = (int) ((float) screenWidth / videoProportion);
    } else {
        lp.width = (int) (videoProportion * (float) screenHeight);
        lp.height = screenHeight;
    }
    surfaceViewFrame.setLayoutParams(lp);

    if (!player.isPlaying()) {
        player.start();         
    }
    surfaceViewFrame.setClickable(true);
}

// callback when the video is over
public void onCompletion(MediaPlayer mp) {
    mp.stop();
    if (updateTimer != null) {
        updateTimer.cancel();
    }
    finish();
}

//pause and resume
public void onClick(View v) {
    if (v.getId() == R.id.surfaceViewFrame) {
         if (player != null) {
            if (player.isPlaying()) {
                player.pause();
                pause.setVisibility(View.VISIBLE);
            } else {
                player.start();
                pause.setVisibility(View.GONE);
            }
        }
    }
}

}
43
caiocpricci2
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        videoView1 = (VideoView) findViewById(R.id.videoview);
                String SrcPath = "/mnt/sdcard/final.mp4";
        videoView1.setVideoPath(SrcPath);
        videoView1.setMediaController(new MediaController(this));
        videoView1.requestFocus();      
        videoView1.start();     
    }
}




<VideoView
    Android:id="@+id/videoview"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:layout_alignParentBottom="true"
    Android:layout_alignParentLeft="true"
    Android:layout_alignParentRight="true"
    Android:layout_alignParentTop="true" >
</VideoView>

これを試してみてください、それは私のために働いています

4
R KiranKumar

現在の賛成のソリューションは機能しますが、元の問題に対するより簡単なソリューションがあるかもしれません。コメント作成者は、すべてをSurfaceViewに変換するコストなしに、同じ方法を使用してVideoViewのサイズを変更できることを正しく指摘しました。私は自分のアプリの1つでこれをテストしましたが、うまくいくようです。 OnPreparedListenerコールバックでVideoViewに計算されたレイアウトパラメーターを追加するだけです。

mInspirationalVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){@Override public void onPrepared(MediaPlayer mp){// mMediaPlayer = mp;

            mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                @Override
                public void onSeekComplete(MediaPlayer mp) {
                    if(isPlaying = true) {
                        stopPosition = 0;
                        mp.start();
                        mVideoProgressTask = new VideoProgress();
                        mVideoProgressTask.execute();
                    }
                }
            });


            // so it fits on the screen
            int videoWidth = mp.getVideoWidth();
            int videoHeight = mp.getVideoHeight();
            float videoProportion = (float) videoWidth / (float) videoHeight;
            int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
            int screenHeight = getWindowManager().getDefaultDisplay().getHeight();

            float screenProportion = (float) screenWidth / (float) screenHeight;
            Android.view.ViewGroup.LayoutParams lp = mInspirationalVideoView.getLayoutParams();

            if (videoProportion > screenProportion) {
                lp.width = screenWidth;
                lp.height = (int) ((float) screenWidth / videoProportion);
            } else {
                lp.width = (int) (videoProportion * (float) screenHeight);
                lp.height = screenHeight;
            }

            mInspirationalVideoView.setLayoutParams(lp);

           ...

        }
    });
2
Clay Martin

これは、ストレッチせずに全画面ビデオで機能する私の機能です。ビデオの両側が自動的にトリミングされます。ポートレートモードとランドスケープモードの両方で機能しました。

実際には answer から取得されました。

    public void onPrepared(MediaPlayer mp) {
        int videoWidth = mediaPlayer.getVideoWidth();
        int videoHeight = mediaPlayer.getVideoHeight();

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int screenWidth = displayMetrics.widthPixels;
        int screenHeight = displayMetrics.heightPixels;

        float scaleY = 1.0f;
        float scaleX = (videoWidth * screenHeight / videoHeight) / screenWidth;

        int pivotPointX = (int) (screenWidth / 2);
        int pivotPointY = (int) (screenHeight / 2);

        surfaceView.setScaleX(scaleX);
        surfaceView.setScaleY(scaleY);
        surfaceView.setPivotX(pivotPointX);
        surfaceView.setPivotY(pivotPointY);

        mediaPlayer.setLooping(true);
        mediaPlayer.start();
    }
1
Hari Krishnan

まあ、それが役立つことを願っています FullscreenVideoView

SurfaceViewと全画面表示に関するすべての退屈なコードを処理し、UIボタンのみに集中できるようにします。

カスタムボタンを作成したくない場合は、FullscreenVideoLayoutを使用できます。

0
Hamiseixas

SurfaceViewはuに最適化された描画面を与えます

public class YourMovieActivity extends Activity implements SurfaceHolder.Callback {
        private MediaPlayer media = null;
        //...

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

            media = new MediaPlayer();
            mSurfaceView = (SurfaceView) findViewById(R.id.surface);
            //...
        }
    }

MediaPlayer呼び出しはtry {}でラップする必要があります。

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        media.setDataSource("Android.resource://" + getPackageName() 
            +"/"+R.raw.video_);
        media.prepare();

            int videoWidth = mp.getVideoWidth();
        int videoHeight = mp.getVideoHeight();

            int screenWidth = getWindowManager().getDefaultDisplay().getWidth();

            Android.view.

ViewGroup.LayoutParams layout = mSurfaceView.getLayoutParams();

    layout.width = screenWidth;

    layout.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth);

    mSurfaceView.setLayoutParams(layout);        

    mp.start();
}
0
Terril Thomas

基礎となる表面ホルダーのサイズを調整しようとしましたか?以下のコードを試してください。画面サイズと同じ幅と高さにサーフェスホルダーを調整する必要があります。アクティビティはタイトルバーなしで全画面表示のままにしてください。

    public class Video extends Activity {
        private VideoView myvid;

        @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.main);
            myvid = (VideoView) findViewById(R.id.myvideoview);
            myvid.setVideoURI(Uri.parse("Android.resource://" + getPackageName() 
                +"/"+R.raw.video_1));
            myvid.setMediaController(new MediaController(this));
            myvid.requestFocus();

            //Set the surface holder height to the screen dimensions
            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            myvid.getHolder().setFixedSize(size.x, size.y);

            myvid.start();
        }
    }
0
Bobbake4

私はこれをCustom VideoViewで解決しました:

VideoViewをParentViewに2つの方法でXMLとプログラムで追加しました。

FullScreenVideoView.Javaという名前のVideoViewのカスタムクラスを追加します。

import Android.content.Context;
import Android.util.AttributeSet;
import Android.widget.VideoView;

public class FullScreenVideoView extends VideoView {
    public FullScreenVideoView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }
}

bind with xmlの方法:

<FrameLayout
   Android:id="@+id/secondMedia"
   Android:layout_width="match_parent"
   Android:layout_height="match_parent">

     <com.my.package.customview.FullScreenVideoView
           Android:layout_width="match_parent"
           Android:layout_height="match_parent" 
           Android:id="@+id/fullScreenVideoView"/>

</FrameLayout>

[〜#〜] or [〜#〜]

方法プログラムで追加 VideoViewにParentView

FullScreenVideoView videoView = new FullScreenVideoView(getActivity());
parentLayout.addView(videoView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));

これがお役に立てば幸いです。

0
Hiren Patel