상세 컨텐츠

본문 제목

[android] 안드로이드에서 비디오 플레이 하기 관련 seekbar 컨트롤 관련

스마트기기개발관련/안드로이드 개발

by AlrepondTech 2020. 9. 20. 01:41

본문

반응형

 

=================================

=================================

=================================

 

 

 

출처: http://stackoverflow.com/questions/26452400/show-mediaplayer-buffering-in-seek-bar-as-secondary-progress

 

I'm using Video view to stream an HLS stream from wowza media server. I want to show the overall buffering just as in YouTube player, what i did is this and I'm able to access seek-bar object and i debugged the code it's not null

videoView.setOnPreparedListener(new OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                int topContainerId = getResources().getIdentifier("mediacontroller_progress", 
                "id", "android");
                
                seekbar = (SeekBar) mediaController.findViewById(topContainerId);

                mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
                    @Override
                    public void onBufferingUpdate(MediaPlayer mp, int percent) {
                        if (percent<seekbar.getMax()) {
                            seekbar.setSecondaryProgress(percent);  
                        }
                    }
                });
            }
        }); 

The problem is i can't see any secondary progress in Media controller seekbar. If any clarification required required please write in comments. Help is really appreciated.

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Use below code and you're goog to go

videoView.setOnPreparedListener(new OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                int topContainerId = getResources().getIdentifier("mediacontroller_progress", 
                "id", "android");
                
                seekbar = (SeekBar) mediaController.findViewById(topContainerId);

                mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
                    @Override
                    public void onBufferingUpdate(MediaPlayer mp, int percent) {
                        if (percent<seekbar.getMax()) {
                            seekbar.setSecondaryProgress(percent);  
                            seekbar.setSecondaryProgress(percent/100);  
                        }
                    }
                });
            }
        }); 

 

 

 

=================================

=================================

=================================

 

 

출처: http://stackoverflow.com/questions/3686729/mediacontroller-positioning-over-videoview

MediaController positioning over VideoView

I have a VideoView that takes up the top half of the Activity in portrait orientation with the bottom half of the screen showing some images and text. I am playing a rtsp video stream in the video view when the Activity starts. I have attached a MediaController to the VideoView via the following code:

MediaController controller = new MediaController(this);
    controller.setAnchorView(this.videoView);
    controller.setMediaPlayer(this.videoView);
    this.videoView.setMediaController(controller);

When I tap the VideoView to bring up the MediaController on the screen I expected the playback controls to appear overlaying the bottom area of the VideoView (the bottom of the MediaController even with the bottom of the VideoView). Instead the MediaController pops up lower down on the screen, overlaying some of the graphics and text I have below the VideoView.

 

Are there some additional steps I need to take to get the MediaController to appear where I want it to on the screen?

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Frankly, I'd just write my own controller. In fact, I did once.
That being said, try setAnchorView() -- by my reading of the source code, the MediaController will appear at the bottom of whatever the anchor view is.

 

I am desperate to figure this out. I posted a question yesterday about extending the MediaController:stackoverflow.com/questions/7881272/… . I've looked at your github code but wasn't able to figure it out. I think I need to override the setAnchorView method so I can begin to place the MediaController wherever I like. Is their a way to make it "float" and position it that way? – Ronnie Oct 25 '11 at 16:56

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Setting the anchor view will only work if the videoview size is known - it will not be upon init. But you can do something like this:

video.setOnPreparedListener(new OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() { 
            @Override
            public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                /*
                 * add media controller
                 */
                mc = new MediaController(YourActivity.this);
                video.setMediaController(mc);
                /*
                 * and set its position on screen
                 */
                mc.setAnchorView(video);
            }
        });
    }
});

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

make sense to call setAnchorView() once view ready to start. i.e. call from onPrepared() – Shubh Feb 6 '14 at 14:13
  setAnchorView(video) uses parent of VideoView to overlay the media controls. If you have a video with fixed height make sure you put it inside a framelayout so that media controls are on top of the video. – PrakashApr 1 '15 at 19:30

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

I encounter the same problem recently, using setAnchorView(videoView) will set the controller fully under VideoView instead hovering on the bottom area of it. My VideoView is one third screen in upper area, so the controller end up covering whatever View under VideoView.

Below is the way I end up doing it without writing full-blown custom controller (only overriding onSizeChanged of MediaController to move anchor up) :

 

Use FrameLayout as an anchor for MediaContoller, wrap it up together with VideoView as below :

<RelativeLayout
    android:id="@+id/videoLayout"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1.3"
    android:layout_gravity="center"
    android:background="#000000">

    <VideoView
        android:id="@+id/videoView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />

    <FrameLayout android:id="@+id/controllerAnchor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true" 
        android:layout_alignParentRight="true" 
        />

</RelativeLayout>

 

Create custom MediaController that will move FrameLayout up (with MediaController that is anchored to it will follow) when its size changed :

public class MyMediaController extends MediaController
{
    private FrameLayout anchorView;


    public MyMediaController(Context context, FrameLayout anchorView)
    {
        super(context);
        this.anchorView = anchorView;       
    }

    @Override
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
    {
        super.onSizeChanged(xNew, yNew, xOld, yOld);

        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) anchorView.getLayoutParams();
        lp.setMargins(0, 0, 0, yNew);

        anchorView.setLayoutParams(lp);
        anchorView.requestLayout();
    }       
}

Use the custom controller above in place of the standard one and then anchor it to the FrameLayout :

protected void onCreate(Bundle savedInstanceState)
{

    //...

    videoView = (VideoView) findViewById(R.id.videoView1);      
    
    videoController = new MyMediaController(this, 
    (FrameLayout) findViewById(R.id.controllerAnchor));               
    
    videoView.setMediaController(videoController);      

    //...       
}

public void onPrepared(MediaPlayer mp) 
{
    videoView.start();              

    FrameLayout controllerAnchor = (FrameLayout) findViewById(R.id.controllerAnchor);
    videoController.setAnchorView(controllerAnchor);                
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

I use this code to solve it.

 

mediaController.setPadding(0, 0, 0, px);

 

to set the mediacontroller view to the position you want. Hope this help you.

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

i found really easy solution.

Just wrap the videoView in a FrameLayout then you can add the MediaController to that FrameLayout from code, like this:

MediaController mc = new MediaController(context);
    videoView.setMediaController(mc);

    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, 
    LayoutParams.WRAP_CONTENT);
    
    lp.gravity = Gravity.BOTTOM;
    mc.setLayoutParams(lp);

    ((ViewGroup) mc.getParent()).removeView(mc);

    ((FrameLayout) findViewById(R.id.videoViewWrapper)).addView(mc);

EDIT: since I posted this answer I ran into a lot of issues with getting it to hide and with controlling its size so what I ended up doing was I just created my own layout with controls that I could animate and work with without headaches

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 //It work good with me

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <VideoView
        android:id="@+id/videoview"
        android:layout_width="640dp"
        android:layout_height="400dp"
        android:layout_centerInParent="true" >
    </VideoView>

        <FrameLayout
            android:id="@+id/videoViewWrapper"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true" >
        </FrameLayout>

    </RelativeLayout>

package com.example.videoview;

import android.app.Activity;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast;
import android.widget.VideoView;

public class MainActivity extends Activity {

    // private String path = "http://clips.vorwaerts-gmbh.de/VfE_html5.mp4";
    private String path = 
    "http://2387227f13276d2e8940-fbe0b8d9df729a57ca0a851a69d15ebb.r55.cf1.rackcdn.com/hero_2012_demo.mp4";

    private VideoView mVideoView;

    MediaController mc;

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

        if (mVideoView != null)
            return;
        /**
         * TODO: Set the path variable to a streaming video URL or a local media
         * file path.
         */

        mVideoView = (VideoView) findViewById(R.id.videoview);
        mVideoView.setOnCompletionListener(new OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                Toast.makeText(MainActivity.this, "The End", Toast.LENGTH_LONG)
                        .show();
            }
        });

        if (path == "") {
            // Tell the user to provide a media file URL/path.
            Toast.makeText(
                    MainActivity.this,
                    "Please edit MainActivity, and set path"
                            + " variable to your media file URL/path",
                    Toast.LENGTH_LONG).show();

        } else {
            /*
             * Alternatively,for streaming media you can use
             * mVideoView.setVideoURI(Uri.parse(path));
             */
            mVideoView.setVideoPath(path);

            mVideoView
                    .setMediaController(new MediaController(MainActivity.this));
            mVideoView.requestFocus();

            mVideoView.setOnPreparedListener(new OnPreparedListener() {

                @Override
                public void onPrepared(MediaPlayer mp) {
                    // TODO Auto-generated method stub
                    mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
                        @Override
                        public void onVideoSizeChanged(MediaPlayer mp,
                                int width, int height) {
                            /*
                             * add media controller
                             */
                            mc = new MediaController(MainActivity.this);
                            mVideoView.setMediaController(mc);
                            /*
                             * and set its position on screen
                             */
                            mc.setAnchorView(mVideoView);

                            ((ViewGroup) mc.getParent()).removeView(mc);

                            ((FrameLayout) findViewById(R.id.videoViewWrapper))
                                    .addView(mc);
                            mc.setVisibility(View.INVISIBLE);
                        }
                    });
                    mVideoView.start();
                }
            });

            mVideoView.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    if (mc != null) {
                        mc.setVisibility(View.VISIBLE);
                        new Handler().postDelayed(new Runnable() {

                            @Override
                            public void run() {
                                mc.setVisibility(View.INVISIBLE);
                            }
                        }, 2000);
                    }

                    return false;
                }
            });

        }
    }

    private RelativeLayout.LayoutParams paramsNotFullscreen, paramsFullscreen;

    /**
     * handle with the configChanges attribute in your manifest
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub
        super.onConfigurationChanged(newConfig);

        if (paramsFullscreen == null) {
            paramsNotFullscreen = (RelativeLayout.LayoutParams) mVideoView
                    .getLayoutParams();
            paramsFullscreen = new LayoutParams(paramsNotFullscreen);
            paramsFullscreen.setMargins(0, 0, 0, 0);
            paramsFullscreen.height = ViewGroup.LayoutParams.MATCH_PARENT;
            paramsFullscreen.width = ViewGroup.LayoutParams.MATCH_PARENT;
            paramsFullscreen.addRule(RelativeLayout.CENTER_IN_PARENT);
            paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        }
        // To fullscreen
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            mVideoView.setLayoutParams(paramsFullscreen);

        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            mVideoView.setLayoutParams(paramsNotFullscreen);
        }
    }

    @Override
    protected void onPause() {
        if (mVideoView.isPlaying()) {
            mVideoView.pause();
        }
        super.onPause();
    }

    @Override
    public void onBackPressed() {
        if (mVideoView != null) {
            mVideoView.stopPlayback();
        }
        finish();
    }
}


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.videoview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.videoview.MainActivity"
            android:configChanges="orientation|screenSize"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Dialog" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Please let me know if you have any problems

 

nope no issues code works fine 

 

=================================

=================================

=================================

 

 

출처: http://stackoverflow.com/questions/11568123/taking-control-of-the-mediacontroller-progress-slider

 

I need to catch touch events to the MediaController progress slider, so that updates to the MediaPlayer don't occur until the finger lifts off the slider.

[ Perhaps my situation is unique: I am playing streaming video that comes in multiple "stacks" for each "program". The next stack is not loaded until the previous one is finished. The slider needs to represent the duration of all stacks, and the progress of the "thumb" needs to represent total duration. This is easily done by overriding the getBufferPercentage(), getCurrentPosition(), and getDuration() methods of MediaPlayerControl ]

More problematic is "scrubbing" (moving the thumb) back and forth along the timeline. If it causes the data source to be set multiple times along with a seekTo for every movement, things very quickly bog down and crash. It would be better if the MediaPlayer did no action until the user has finished the scrub.

As others have written, Yes it would be best to write my own implementation of the MediaController. But why redo all that work? I tried extending MediaController, but that got complicated quickly. I just wanted to catch the touch events to the slider!

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

One is able to get a handle to the elements of MediaController:

final int topContainerId1 = getResources().getIdentifier("mediacontroller_progress", "id", "android");
final SeekBar seekbar = (SeekBar) mController.findViewById(topContainerId1);

Then set a listener on the seekbar, which will require you to implement its three public methods:

seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        // Log.i("TAG", "#### onProgressChanged: " + progress);
        // update current position here
        }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // Log.i("TAG", "#### onStartTrackingTouch");
        // this tells the controller to stay visible while user scrubs
        mController.show(3600000);
        // if it is possible, pause the video
        if (playerState == MPState.Started || playerState == MPState.Paused) {
            mediaPlayer.pause();
            playerState = MPState.Paused;
        }
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int seekValue = seekBar.getProgress();
        int newMinutes = Math.round((float)getTotalDuration() * 
        (float)seekValue / (float)seekBar.getMax());
        
        // Log.i("TAG", "#### onStopTrackingTouch: " + newMinutes);
        mController.show(3000); // = sDefaultTimeout, hide in 3 seconds
    }
});

Caveats: This is not updating the current position as you scrub, the left-hand-side TextView time value. (I had a truly remarkable way to do this which this margin is too small to contain).

 

 

=================================

=================================

=================================

 

 

출처: http://bcho.tistory.com/1056

 

동영상 서비스를 하다보니, 실제로 비디오 플레이어를 어떻게 구현하는 지가 궁금해서 찾아봤는데, 생각보다 안드로이드의 비디오 플레이어 구현은 간단해 보인다. 

내부적으로 MediaPlayer라는 컴포넌트를 사용하는데, 이 MediaPlayer는 조금 더 미세한 컨트롤이 가능하고 이를 한단계 더 쌓아 놓은 VideoView라는 것이 사용방법이 쉽다. 또한 구버전의 안드로이드에서는 MediaPlayer 기능이 잘 작동하지 않는 부분이 있기 때문에, VideoView를 사용하는 것이 조금 더 안정적일 수 있다.

 

내장된 플레이어로 지원되는 프로토콜은 다음과 같다.

RTSP

HTTP/HTTPS Progressive Streaming

HTTP/HTTPS Live Streaming (HLS)

MPEG-2 TS 

Protocol version 3 (Android 4.0 & above)

Protocol version 2 (Android 3.X)

3.0 이하 버전은 지원 안됨

 

 

 

MediaPlayer는 실시간 방송을 위한 RTMP나 HTTP 기반의  DASH등 다양한 프로토콜을 지원하지 않고, 기능상에 제약이 있는데, 이러한 기능상의 제약을 없애고 플레이어를 확장하려면, MediaCodec과  MediaExtractor 클래스를 이용하여 직접 플레이어를 만들어야 하는데, 번거롭고 다른 대안으로는 조금 더 다양한 기능을 제공하는 오픈 소스 플레이어를 활용하는 방법이 있다.

https://developer.android.com/guide/topics/media/exoplayer.html

를 보면 ExoPlayer를 소개하고 있는데, 안드로이드 공식 개발자 페이지에서 소개하는 것을 보면 신뢰성이 꽤 높은 듯 하다.

 

배경 설명은 이정도로 하고, 여기서는 간단하게 VieoView를 이용한 간단한 플레이어를 만들어 보도록 한다.

 

다음과 같은 기능을 구현한다.

 

URL 입력 (Progressive download 또는 HLS)

재생

일시 멈춤

네비게이션 바 출력

전체 시간 출력

 

완성된 앱의 UI는 다음과 같다. 

 

가장 기본적인 기능인데, 앞으로 가기나, 뒤로 가기,음소거,음켜기 등도 구현이 어렵지 않으니 쉽게 추 가 할 수 있다.

 

참고 

미디어 플레이어 예제  http://www.tutorialspoint.com/android/android_mediaplayer.htm

전체화면 보기 예제

http://javaexpert.tistory.com/365

 

레이아웃 코드는 다음과 같다. 

 

 activity_main.xml

activity_main.xml
0.00MB

 

다음은, MainActivity.java  코드이다.

 

 MainActivity.java

MainActivity.java
0.00MB

 

코드를 하나하나 뜯어 보면, 먼저 OnCreate에서 객체가 생성될때, VideoView 객체와 비디오 플레이 진행상황을 표시할 SeekBar에 대한 레퍼런스를 저장해놓는다.

 

    final static String SAMPLE_VIDEO_URL = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";

    VideoView videoView;

    SeekBar seekBar;

    Handler updateHandler = new Handler();

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        EditText tvURL = (EditText)findViewById(R.id.etVieoURL);

        tvURL.setText(SAMPLE_VIDEO_URL);

 

        videoView = (VideoView)findViewById(R.id.videoView);

        // MediaController mc = new MediaController(this);

        // videoView.setMediaController(mc);

 

        seekBar = (SeekBar)findViewById(R.id.seekBar);

    }

 

다음 “LOAD” 버튼을 누르면 지정된 URL에서 MP4 파일을 읽어와서 플레이를 시작하도록 한다.

 

    public void loadVideo(View view) {

        //Sample video URL : http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_2mb.mp4

        EditText tvURL = (EditText) findViewById(R.id.etVieoURL);

        String url = tvURL.getText().toString();

 

        Toast.makeText(getApplicationContext(), "Loading Video. Plz wait", Toast.LENGTH_LONG).show();

        videoView.setVideoURI(Uri.parse(url));

        videoView.requestFocus();

 

        // 토스트 다이얼로그를 이용하여 버퍼링중임을 알린다.

        videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {

 

            @Override

            public boolean onInfo(MediaPlayer mp, int what, int extra) {

                switch(what){

                    case MediaPlayer.MEDIA_INFO_BUFFERING_START:

                        // Progress Diaglog 출력

                        Toast.makeText(getApplicationContext(), "Buffering", Toast.LENGTH_LONG).show();

                        break;

                    case MediaPlayer.MEDIA_INFO_BUFFERING_END:

                        // Progress Dialog 삭제

                        Toast.makeText(getApplicationContext(), "Buffering finished.\nResume playing", Toast.LENGTH_LONG).show();

                        videoView.start();

                        break;

                }

                return false;

            }

        }

 

        );

 

        // 플레이 준비가 되면, seekBar와 PlayTime을 세팅하고 플레이를 한다.

        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

            @Override

            public void onPrepared(MediaPlayer mp) {

                videoView.start();

                long finalTime = videoView.getDuration();

                TextView tvTotalTime = (TextView) findViewById(R.id.tvTotalTime);

                tvTotalTime.setText(String.format("%d:%d",

                                TimeUnit.MILLISECONDS.toMinutes((long) finalTime),

                                TimeUnit.MILLISECONDS.toSeconds((long) finalTime) -

                                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) finalTime)))

                );

                seekBar.setMax((int) finalTime);

                seekBar.setProgress(0);

                updateHandler.postDelayed(updateVideoTime, 100);

                //Toast Box

                Toast.makeText(getApplicationContext(), "Playing Video", Toast.LENGTH_SHORT).show();

            }

        });

    }

 

하나씩 뜯어보면, 비디오 플레이는  viewView.SetVideoURI(URI)를 지정하면 비디오가 플레이가 시작되고, videoView.requestFocus()를 하면, 해당 view에 포커스를 한다.

다음으로 videoView.start()를 하면 플레이가 되는데, 중간에 몇가지 추가 코드가 들어가 있다.

 

먼저 이 예제는 로컬에 있는 파일을 플레이 하는 것이 아니라 Remote에 있는 MP4파일을 http로 다운 받으면서 플레이하는 Progressive download 형태의 플레이 방식이기 때문에 네트워크 상태에 따라서 로딩 시간이 걸릴 수 있다. 다음 videoView.setOnInfoListner는 VideoView의 상태가 변경되었을때 호출되는 콜백함수로, 버퍼링이 시작될때와 버퍼링이 끝날때의 이벤트를 잡아서 토스트 다이얼로그를 띄워주는 부분이다. 아래 구현에서는 토스트 다이얼로그를 사용했지만 Progress Dialog등을 이용하여 버퍼링 중임을 알려줄 수 도 있다.

버퍼링이 시작될때는 MediaPlayer.MEDIA_INFO_BUFFERING_START라는 이벤트를 보내고, 버퍼링이 끝날때는 MediaPlayer.MEDIA_INFO_BUFFERING_END라는 이벤트를 보내기 때문에, 이 시점에 맞춰서 버퍼링중임을 알리는 메세지를 보이거나 감추면 된다.

 

        // 토스트 다이얼로그를 이용하여 버퍼링중임을 알린다.

        videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {

 

            @Override

            public boolean onInfo(MediaPlayer mp, int what, int extra) {

                switch(what){

                    case MediaPlayer.MEDIA_INFO_BUFFERING_START:

                        // Progress Diaglog 출력

                        Toast.makeText(getApplicationContext(), "Buffering", Toast.LENGTH_LONG).show();

                        break;

                    case MediaPlayer.MEDIA_INFO_BUFFERING_END:

                        // Progress Dialog 삭제

                        Toast.makeText(getApplicationContext(), "Buffering finished.\nResume playing", Toast.LENGTH_LONG).show();

                        videoView.start();

                        break;

                }

                return false;

            }

        }

 

        );

 

다음 코드 부분은 버퍼링이 다 끝나고 처음 플레이 준비가 되었을 때 전체 플레이 시간을 세팅하고 SeekBar의 전체 길이등을 세팅하는 초기 작업을 하기 위한 콜백 함수이다. setOnPreparedListner에서, MediaPlayer.OnPreparedListner를 콜백함수로 다음과 같이 정의한다.

 

        // 플레이 준비가 되면, seekBar와 PlayTime을 세팅하고 플레이를 한다.

        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

            @Override

            public void onPrepared(MediaPlayer mp) {

                videoView.start();

                long finalTime = videoView.getDuration();

                TextView tvTotalTime = (TextView) findViewById(R.id.tvTotalTime);

                tvTotalTime.setText(String.format("%d:%d",

                                TimeUnit.MILLISECONDS.toMinutes((long) finalTime),

                                TimeUnit.MILLISECONDS.toSeconds((long) finalTime) -

                                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) finalTime)))

                );

                seekBar.setMax((int) finalTime);

                seekBar.setProgress(0);

                updateHandler.postDelayed(updateVideoTime, 100);

                //Toast Box

                Toast.makeText(getApplicationContext(), "Playing Video", Toast.LENGTH_SHORT).show();

            }

        });

 

먼저 플레이 준비가 되면 videoView.start() 메서드로 동영상 플레이를 시작한다.

다음으로 vieoView.getDuration() 메서드를 이용하여 전체 동영상 플레이 시간을 받아서 분/초로 변환한후 출력하고, SeekBar의 Max값을 총 플레이 시간으로 저장한다. 그리고 100ms마다 seekBar의 플레이 상태를 이동시키기 위해서 updateHandler에 updateVideoTime 함수를 100ms 이후에 실행하도록 지정한다.

updateVideoTime 함수는 다음과 같다.

 

    // seekBar를 이동시키기 위한 쓰레드 객체

    // 100ms 마다 viewView의 플레이 상태를 체크하여, seekBar를 업데이트 한다.

    private Runnable updateVideoTime = new Runnable(){

        public void run(){

            long currentPosition = videoView.getCurrentPosition();

            seekBar.setProgress((int) currentPosition);

            updateHandler.postDelayed(this, 100);

 

        }

    };

 

만약에 안드로이드 에뮬레이터에서 실행을 하게 되면 일부 MP4 동영상은 Decoder를 찾을 수 없다는 에러가 나올 수 있는데, 이는 MP4 확장명을 가지더라도, 내부 인코딩 방식이 각기 틀리기 때문에, 안드로이드 에뮬레이터에서는 일부 디코더만 지원하기 때문에, 제대로 플레이가 되지 않을 수 있다.  실제 기기를 연결하면, 실 기기에는 대부분의 MP4 디코더가 탑재되어 있기 때문에, 문제 없이 동영상이 플레이 된다.

그렇지만 실제로 동영상을 서비스하는 플레이어를 만들려면, 동영상을 플레이어에 최적화된 형태로 다시 인코딩을 해서 플레이를 하는 것이 좋다. 화면 해상도에 따른 품질 차이나, 압축 방식 그리고 초당 프레임수 (FPS)등에 따라서 영향을 받기 때문에 최적의 인코딩 포맷을 찾은 후에, 그 포맷에 따라서 인코딩을 하는 것이 좋으며, 이런 인코딩 전문 플랫폼으로는 예전 엠군에서 제공하는 위켄디오나 해외의 zencoder등과 같인 인코딩 플랫폼을 사용하면 손쉽게 연동이 가능하다. 

 

 

참고 자료

http://www.techotopia.com/index.php/An_Android_Studio_VideoView_and_MediaController_Tutorial#Introducing_the_Android_MediaController_Class

 

 

=================================

=================================

=================================

 

 

 

출처: http://www.androidside.com/bbs/board.php?bo_table=b49&wr_id=97385

 

 

미디어 플레이어를 만들고 있는데요.

seekbar 구간을 찍으면 그 구간이 재생은 되는데요.

재생중에 seekbar가 움직이지를 않네요... 소리는 납니다...

대체 뭐가 잘못된건지 모르겠어요 ㅠㅠ...

 

 

public class AudioPlayer extends Activity implements OnClickListener, Runnable, OnSeekBarChangeListener {

   

private MediaPlayer mp = new MediaPlayer(); // MediaPlayer 객체

private ImageButton Load;

private ImageButton Play;

private ImageButton Pause;

private SeekBar sb;

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);        

 

        Play = (ImageButton)findViewById(R.id.imageButton1);

        Pause = (ImageButton)findViewById(R.id.imageButton2);

        Load = (ImageButton)findViewById(R.id.imageButton3);

        sb = (SeekBar)findViewById(R.id.seekBar1);

        

        Load.setOnClickListener(this);

        Play.setOnClickListener(this);

        Pause.setOnClickListener(this);

        sb.setOnSeekBarChangeListener(this);

    }

    

    public void onClick(View v) {

     switch(v.getId()) {

    

     case R.id.imageButton3:

     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);

     intent.setType("audio/*");

startActivityForResult(intent, 0); 

break;

 

     case R.id.imageButton2:

     mp.pause();

break;

 

     case R.id.imageButton1:

     if(!mp.isPlaying()){

try {

mp.prepare();

sb.setVisibility(ProgressBar.VISIBLE);

         sb.setProgress(0);

         sb.setMax(mp.getDuration());

} catch (Exception e){

e.printStackTrace();

}

mp.start();

}

break;

     }

    }

    

    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data){

super.onActivityResult(requestCode, resultCode, data);

if(resultCode == Activity.RESULT_OK && requestCode == 0){

try {

mp.setDataSource(this, data.getData());

Play.setEnabled(true);

} catch (Exception e){

e.printStackTrace();

}

}

    }

    

    public void run() {

     int current = 0;

     while(mp!=null) {

     try {

     Thread.sleep(1000);

     current = mp.getCurrentPosition();    

     } catch (Exception e) {

     e.printStackTrace();

     }

     if(mp.isPlaying()) {

sb.setProgress(current);

}

     }

    }

    

public void onProgressChanged(SeekBar seekBar, int progress,

boolean fromUser) {

// TODO Auto-generated method stub

mp.seekTo(sb.getProgress());

}

 

public void onStartTrackingTouch(SeekBar seekBar) {

// TODO Auto-generated method stub

 

}

 

public void onStopTrackingTouch(SeekBar seekBar) {

// TODO Auto-generated method stub

 

mp.seekTo(sb.getProgress());

}

 

@Override

    public void onDestroy(){

    

super.onDestroy();

mp.release();

}

}

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

동영상플레이를 Start하실때 

 

mMediaPlayer.seekTo(mSeekBar.getProgress());와 같이 한번 해보세요...

 

 

 

 

반응형

 

 

728x90

 

 

=================================

=================================

=================================

 

 

 

출처ㅣ http://www.xtx.kr/kiss2me/start.php?id=TG2&page=4&divpage=1&sn=off&ss=on&sc=off&select_arrange=headnum&desc=asc&no=1201

 

SeekBar + Thread 사용하여 미디어 플레이 하기를 구현한 예제입니다
[시작] 버튼, [일지정지] 버튼, [재시작] 버튼, [정지] 버튼 의 기능도 구현해 봅니다.


1. 미디어 파일 (첨부) 준비,  raw 폴더 밑에 별도의 폴더 만들어 복사-붙여넣기로 끌어옵니다.
2. MediaPlayer 객체, SeekBar 객체 생성
3. Start를 누르면 MediaPlayer.create() 로 MediaPlayer 객체 생성 (이때 raw 에 복사한 미디어 파일 지정,  소스에서는 R.raw.chacha).   그리고 start() 메소드로 연주 시작.  이때 SeekBar의 쓰레드를 start() 시켜 줍니다.

4.  SeekBar.setOnSeekBarChangeListener() 구현하여 임의의 지점에서 플레이 가능케 함


activity_main.xml


    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="MediaPlayer 활용"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1"
        android:text="시작" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:visibility="invisible"
        android:text="일시정지" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button2"
        android:layout_below="@+id/button2"
        android:visibility="invisible"
        android:text="재시작" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button3"
        android:layout_below="@+id/button3"
        android:visibility="invisible"
        android:text="종료" />

    <SeekBar
        android:id="@+id/seekBar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button4"
        android:layout_below="@+id/button4"
        android:layout_marginTop="18dp" />

</RelativeLayout>

메인액티비티소스
public class MainActivity extends ActionBarActivity {
    MediaPlayer mp; // 음악 재생을 위한 객체
    int pos; // 재생 멈춘 시점
    private Button bStart;
    private Button bPause;
    private Button bRestart;
    private Button bStop;
    SeekBar sb; // 음악 재생위치를 나타내는 시크바
    boolean isPlaying = false; // 재생중인지 확인할 변수

    class MyThread extends Thread {
        @Override
        public void run() { // 쓰레드가 시작되면 콜백되는 메서드
            // 씨크바 막대기 조금씩 움직이기 (노래 끝날 때까지 반복)
            while(isPlaying) {
                sb.setProgress(mp.getCurrentPosition());
            }
        }
    }

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

        sb = (SeekBar)findViewById(R.id.seekBar1);
        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onStopTrackingTouch(SeekBar seekBar) {
                isPlaying = true;
                int ttt = seekBar.getProgress(); // 사용자가 움직여놓은 위치
                mp.seekTo(ttt);
                mp.start();
                new MyThread().start();
            }
            public void onStartTrackingTouch(SeekBar seekBar) {
                isPlaying = false;
                mp.pause();
            }
            public void onProgressChanged(SeekBar seekBar,int progress,boolean fromUser) {
                if (seekBar.getMax()==progress) {
                    bStart.setVisibility(View.VISIBLE);
                    bStop.setVisibility(View.INVISIBLE);
                    bPause.setVisibility(View.INVISIBLE);
                    bRestart.setVisibility(View.INVISIBLE);
                    isPlaying = false;
                    mp.stop();
                }
            }
        });

        bStart = (Button)findViewById(R.id.button1);
        bPause = (Button)findViewById(R.id.button2);
        bRestart=(Button)findViewById(R.id.button3);
        bStop  = (Button)findViewById(R.id.button4);

        bStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // MediaPlayer 객체 초기화 , 재생
                mp = MediaPlayer.create(
                        getApplicationContext(), // 현재 화면의 제어권자
                        R.raw.chacha); // 음악파일
                mp.setLooping(false); // true:무한반복
                mp.start(); // 노래 재생 시작

                int a = mp.getDuration(); // 노래의 재생시간(miliSecond)
                sb.setMax(a);// 씨크바의 최대 범위를 노래의 재생시간으로 설정
                new MyThread().start(); // 씨크바 그려줄 쓰레드 시작
                isPlaying = true; // 씨크바 쓰레드 반복 하도록

                bStart.setVisibility(View.INVISIBLE);
                bStop.setVisibility(View.VISIBLE);
                bPause.setVisibility(View.VISIBLE);
            }
        });

        bStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 음악 종료
                isPlaying = false; // 쓰레드 종료

                mp.stop(); // 멈춤
                mp.release(); // 자원 해제
                bStart.setVisibility(View.VISIBLE);
                bPause.setVisibility(View.INVISIBLE);
                bRestart.setVisibility(View.INVISIBLE);
                bStop.setVisibility(View.INVISIBLE);

                sb.setProgress(0); // 씨크바 초기화
            }
        });

        bPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 일시중지
                pos = mp.getCurrentPosition();
                mp.pause(); // 일시중지
                bPause.setVisibility(View.INVISIBLE);
                bRestart.setVisibility(View.VISIBLE);
                isPlaying = false; // 쓰레드 정지
            }
        });
        bRestart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 멈춘 지점부터 재시작
                mp.seekTo(pos); // 일시정지 시점으로 이동
                mp.start(); // 시작
                bRestart.setVisibility(View.INVISIBLE);
                bPause.setVisibility(View.VISIBLE);
                isPlaying = true; // 재생하도록 flag 변경
                new MyThread().start(); // 쓰레드 시작
            }
        });
    } // end of onCreate

    @Override
    protected void onPause() {
        super.onPause();
        isPlaying = false; // 쓰레드 정지
        if (mp!=null) {
            mp.release(); // 자원해제
        }
        bStart.setVisibility(View.VISIBLE);
        bStop.setVisibility(View.INVISIBLE);
        bPause.setVisibility(View.INVISIBLE);
        bRestart.setVisibility(View.INVISIBLE);
    }
} // end of class

 

 

=================================

=================================

=================================

 

 

출처: http://www.androidside.com/bbs/board.php?bo_table=B49&wr_id=50273

 

그냥 간단하게

동영상 xml에 videoview 를 만들고

 

java에서 다음과 같은 기본 동영상 재생을 하게끔 

하였습니다.

 

하고 싶은 것은 이 동영상이 한번만 돌고 끝나는데 무한반복재생이 되도록 하고 싶습니다.

아무리 몇시간검색해도 제 수준의 답이 없어서 이렇게 질문을 드립니다. ㅠ.ㅠ

 

package com.supergenius.sgintro4;

 

import android.app.Activity;

import android.net.Uri;

import android.os.Bundle;

 

import android.widget.VideoView;

 

public class SG_Intro_mp4 extends Activity {

 

private VideoView mVideoView;

 

@Override

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    

    setContentView(R.layout.intro);

    

    mVideoView = (VideoView) findViewById(R.id.videoView1);

    mVideoView.setVideoURI(Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.rainy_day));

    mVideoView.requestFocus();

    mVideoView.start(); 

 

 }

 

}

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

안드로이드 디벨로퍼에 있는 레퍼런스를 보니깐 
setOnCompletionListener(MediaPlayer.OnCompletionListener l)  이런게 있던데
이름만 봐서는 재생 완료후에 불려질꺼 같은데 말이죠


검색은 안해봐서 모르곘군요

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){

     public void onCompletion(MediaPlayer mp){

         mVideoView.start();

     }

});

요로코롬 하시면 되겠네요.

물론 직접 해본건 아닙니다


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

너무 감사합니다. 그 코드로 해보았더니 잘 돌아 가네요 ^^

OSKiller님도 진심으로 감사합니다.

 

 

=================================

=================================

=================================

 

 

출처: http://androiddeveloper.tistory.com/69

 

예전에 사운드 재생을 해봤는데요
오늘은 동영상을 재생을 한번 해보겠습니다.
온라인상에 있는 동영상을 재생하는 방법과 동영상파일을 첨부해서 재생시키는 두가지 방법을 살펴볼텐데요.
먼저 VideoView 도구를 이용한 첨부파일 동영상을 재생시키는 것을 살펴보겠습니다.

재생할 동영상을 res폴더에 raw폴더를 생성 후 raw폴더에 재생할 동영상을 넣습니다.

 

 


안드로이드에서 지원하는 동영성 코덱을 잘 알아보시고 넣어주시기 바랍니다.
필자는 wmv가 안되는 것을 모르고 왜 안되지 왜 안되는거야 하면서 이리저리 찾다가 알았습니다.
mp4가 기본적으로 지원하고 avi도 지원하는 것 같습니다.

그럼 VideoView를 사용하여 동영상을 재생해보겠습니다.

먼저 비디오를 재생하면 기본적으로 화면이 어떻해 재생되는 지 알죠?
가로입니다. 가로고정을 시켜줘야 합니다. 세로로해도 무난하지만 기본에 충실합시다.

 

 



프로젝트 생성

Project name : ExamOptionsMenu
Build Target : Android 2.1
Package name : jsh.exam.option
Create Activity : main
Min SDK Version : 7



src

main.java

 

비디오뷰main.java소스.txt
0.00MB

 

 

package jsh.exam.video;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;

public class ExamvideoActivity extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // 생성한 비디오뷰를 선언
  VideoView videoView = (VideoView) findViewById(R.id.videoView1);

  // 비디오뷰를 커스텀하기 위해서 미디어컨트롤러 객체 생성
  MediaController mediaController = new MediaController(this);

  // 비디오뷰에 연결
  mediaController.setAnchorView(videoView);
  // 안드로이드 res폴더에 raw폴더를 생성 후 재생할 동영상파일을 넣습니다.
  Uri video = Uri.parse("android.resource://" + getPackageName()
    + "/raw/동영상파일이름");
  
  //비디오뷰의 컨트롤러를 미디어컨트롤로러 사용
  videoView.setMediaController(mediaController);
  
  //비디오뷰에 재생할 동영상주소를 연결
  videoView.setVideoURI(video);

  //비디오뷰를 포커스하도록 지정
  videoView.requestFocus();

  //동영상 재생
  videoView.start();

 }
}


res

main.xml

 

 

 

 

 

 

 

 

비디오뷰main.xml소스.txt
0.00MB

 


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android
"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <VideoView
  android:id="@+id/videoView1"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_gravity="center"></VideoView>
</LinearLayout>


실행결과

 

 





프로젝트안에 첨부된 동영상파일이
재생되는 것을 볼 수 있습니다.

 

 

=================================

=================================

=================================

 

 

출처: https://realm.io/kr/news/android-videoview/

안드로이드에서 오디오와 비디오 재생을 모두 담당하는 기본 API인 MediaPlayer는 사용법이 비교적 간단하지만, 그보다 더 편하게 영상을 재생할 방법이 있습니다. MediaPlayer와 영상이 재생되는 SurfaceView를 래핑한 VideoPlayer를 사용해서 손쉽게 비디오를 재생하는 방법을 소개합니다.


소개

안드로이드의 MediaPlayer는 오디오와 비디오 재생을 담당하는 기본 API로, 비디오 재생을 위해서는 SurficeView를 준비하고 MediaPlayer를 생성해서 비디오를 재생해야 합니다. 그러나 VideoView 클래스를 사용하면 이런 작업을 더 간단하게 진행할 수 있습니다. 특히 멀티미디어 재생을 위한 UI인 MediaController를 쉽게 연결할 수 있고 기본적인 제공 기능이 많은 것이 장점입니다. 이 글에서는 VideoView의 사용법을 기초적인 예제를 통해 단계별로 설명합니다.

VideoView

VideoView란 다양한 자원에서 영상을 불러올 수 있는 동영상 재생 전담 위젯입니다. MediaController라는 UI를 제공하고 scaling과 tinting 등 다양한 디스플레이 기능을 제공하고 있어 간편하게 사용할 수 있습니다.

MediaController

MediaController는 VideoView의 컨트롤 UI를 담은 뷰입니다. 아래 그림처럼 기본적으로 재생/정지, 되감기, 빨리감기와 Progress Slider를 내장하고 있습니다.

 

기본 설정은 영상을 터치하면 자동으로 올라오는 것입니다. 만약 수동으로 보이고 싶을 때는 show(), 감추고 싶을 경우 hide() 메서드를 사용할 수 있습니다. 현재 보이고 있는지 확인하고 싶을 때는 boolean을 리턴하는 isShowing() 메서드를 활용하세요.

미디어 재생을 위한 권한 설정

MediaPlayer와 마찬가지로 VideoView를 사용할 때에도 외부 URL로부터 동영상을 스트리밍하기 위해서는 인터넷 권한이 필요합니다. 또한, 영상을 재생하는 도중에 화면이 어두워지거나 꺼지고 잠기는 것을 막으려면 웨이크락 권한이 필요합니다. 각 권한은 다음처럼 Manifest.xml 파일에서 설정할 수 있습니다.

 

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" />VideoView 설정 - xml

 

VideoView를 생성해서 비디오 재생을 준비하는 과정은 MediaPlayer에 비해 아주 단순합니다. 기본 생성자에 인자를 전달하고 setVideoPath나 URI를 호출하면 됩니다.

 

아래 예제를 보면 VideoView를 생성하는 것이 얼마나 간단한지 알 수 있습니다. 먼저 xml에 VideoView를 만듭니다. VideoView는 SurfaceView의 서브클래스이기 때문에 따로 SurfaceView를 준비하지 않아도 됩니다.

<VideoView android:id=“@+id/videoView”
android:layout_width=“400dp”
android:layout_height=“240dp” />

 

액티비티에서 VideoView를 연결해준 후 MediaController를 설정합니다.

 

public class VideoViewActivity extends Activity {
	@override
	public void onCreate(Bundle savedInstanceState) {
		//
		VideoView videoView = (VideoView)findViewById(R.id.videoView);
		//
		videoView.setVideoPath( // );
		// videoView.setVideoURL(url);
		//
		final MediaController mediaController = 
			new MediaController(this);
		videoView.setMediaController(mediaController);
	}
}

 

VideoView를 사용할 모든 준비가 끝났습니다. 과연 이 상태로 사용자들은 비디오를 볼 수 있을까요?
예제대로라면 사용자는 맨 처음 검은색 VideoView 화면을 만나게 됩니다. 사용자가 VideoView를 터치하면 MediaController가 나타나서 컨트롤을 할 수 있는 UI를 제공합니다. 기본 설정은 MediaController의 재생 버튼을 눌러야 비로소 영상이 보이게 됩니다.

 

VideoView UX 개선

사용자가 느낄 당황스러움을 눈치채셨나요? 기본 VideoView 화면은 아무런 인터렉션을 유도하지 않는 검은색 화면입니다. 따라서 유투브처럼 영상의 미리보기를 제공하려면 약간의 개선이 필요합니다.

첫 번째 해결책은 MediaStore의 thumbnail을 활용해서 preview를 직접 만드는 방법입니다. 내부 파일을 가져올 때 간단하게 적용할 수 있습니다.

 

String videoFile = "//";
Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(videoFile,
        MediaStore.Images.Thumbnails.MINI_KIND);
        
VideoView videoView = (VideoView)findViewById(R.id.videoView);
BitmapDrawable bitmapDrawable = new BitmapDrawable(thumbnail);
videoView.setBackgroundDrawable(bitmapDrawable);

 

두 번째 해결책은 VideoView의 seekTo()를 사용해서 영상 시작 지점을 살짝 감아두는 것입니다. 다만 Nexus 5.0에서 적용되지 않는다는 리포트가 있으므로 모든 기기에 적용되지 않을 위험성이 있습니다.

세 번째 해결책은 영상을 바로 재생한 후 Thread를 사용하여 사용자가 인지하지 못할 짧은 시간에 멈추는 방법입니다. 가장 복잡하긴 하지만, MediaController도 같이 보여주는 코드도 넣을 수 있어서 재생할 수 있는 영상과 UI가 제공되고 있다는 것을 직관적으로 파악할 수 있습니다.

final MediaController mediaController = 
	new MediaController(this);
videoView.setMediaController(mediaController);

videoView.start();

videoView.postDelayed(new Runnable() {
    @Override
    public void run() {
        mediaController.show(0);
        videoView.pause();
    }
}, 100);

 

기초적인 예제로 전체 보기 등 아직 개선해야 할 부분이 많습니다. 더 자세한 내용은 안드로이드 개발자 참조문서를 확인해 주세요.

 

 

=================================

=================================

=================================

 

 

출처: http://hashcode.co.kr/questions/2116/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%8F%99%EC%98%81%EC%83%81-%EC%96%B4%ED%94%8C%EC%9D%84-http-get%EB%B0%A9%EC%8B%9D%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EB%A9%B4-%EC%95%88%EB%90%98%EB%82%98%EC%9A%94

 

 

이미지를 이용하는 방식보다는 VideoView를 이용하는게 좋겠네요.

아래는 검색해서 찾은 샘플 코드에요.

 

@Override
protected void onCreate(Bundle savedInstanceState)
     // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    try {
        setContentView(R.layout.videodisplay);
        String link="http://s1133.photobucket.com/albums/m590/Anniebabycupcakez/?action=view&amp; current=1376992942447_242.mp4";
        VideoView videoView = (VideoView) findViewById(R.id.VideoView);
        MediaController mediaController = new MediaController(this);
        mediaController.setAnchorView(videoView);
        Uri video = Uri.parse(link);
        videoView.setMediaController(mediaController);
        videoView.setVideoURI(video);
        videoView.start();
    } catch (Exception e) {
        // TODO: handle exception
        Toast.makeText(this, "Error connecting", Toast.LENGTH_SHORT).show();
    }
}

 

=================================

=================================

=================================

 

 

 

반응형


관련글 더보기

댓글 영역