ExoPlayer 사용법 예시

The easiest way to get started using ExoPlayer is to add it as a gradle dependency. You need to make sure you have the jcenter repository included in the build.gradle file in the root of your project:

repositories {
jcenter()
}

Next, include the following in your module’s build.gradle file:

compile 'com.google.android.exoplayer:exoplayer:r2.2.0'

1. Your Layout File

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.exoplayer2.ui.SimpleExoPlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        app:resize_mode="fill"/>

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone"/>

</FrameLayout>

2. Your Class File(Activity)

    public class VideoPlayerActivity extends AppCompatActivity implements ExoPlayer.EventListener {

    private SimpleExoPlayerView simpleExoPlayerView;
    private String hlsVideoUri = "http://playertest.longtailvideo.com/adaptive/bbbfull/bbbfull.m3u8";
    private SimpleExoPlayer player;
    private ProgressBar progressBar;

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

        // 1. Create a default TrackSelector
        Handler mainHandler = new Handler();
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

        // 2. Create a default LoadControl
        LoadControl loadControl = new DefaultLoadControl();


        // 3. Create the player
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);

        simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
        simpleExoPlayerView.setPlayer(player);

        // Measures bandwidth during playback. Can be null if not required.
        DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
        // Produces DataSource instances through which media data is loaded.
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                Util.getUserAgent(this, "Exo2"), defaultBandwidthMeter);
        // Produces Extractor instances for parsing the media data.
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
        // This is the MediaSource representing the media to be played.
        HlsMediaSource hlsMediaSource = new HlsMediaSource(Uri.parse(hlsVideoUri), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() {
            @Override
            public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {

            }

            @Override
            public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {

            }

            @Override
            public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {

            }

            @Override
            public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {

            }

            @Override
            public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {

            }

            @Override
            public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {

            }
        });

        player.addListener(this);
        player.prepare(hlsMediaSource);
        simpleExoPlayerView.requestFocus();
        player.setPlayWhenReady(true);

        progressBar = (ProgressBar) findViewById(R.id.progressBar);
    }

    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest) {

    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

        switch (playbackState) {
            case Player.STATE_BUFFERING:
                //You can use progress dialog to show user that video is preparing or buffering so please wait
                progressBar.setVisibility(View.VISIBLE);
                break;
            case Player.STATE_IDLE:
                //idle state
                break;
            case Player.STATE_READY:
                // dismiss your dialog here because our video is ready to play now
                progressBar.setVisibility(View.GONE);
                break;
            case Player.STATE_ENDED:
                // do your processing after ending of video
                break;
        }
    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {

        AlertDialog.Builder adb = new AlertDialog.Builder(VideoPlayerActivity.this);
        adb.setTitle("Could not able to stream video");
        adb.setMessage("It seems that something is going wrong.\nPlease try again.");
        adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                finish(); // take out user from this activity. you can skip this
            }
        });
        AlertDialog ad = adb.create();
        ad.show();
    }

    @Override
    public void onPositionDiscontinuity() {

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (player != null) {
            player.setPlayWhenReady(false); //to pause a video because now our video player is not in focus
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        player.release();
    }
}

I think this is enough for beginner. Also keep in mind that this library’s standard audio and video components rely on Android’s MediaCodec API, which was released in Android 4.1 (API level 16). So it will not work on android 4.0 and below.

Don’t forget to add this permission to the manifest file :

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

 

-시간이 좀 지나서 그대로는 안되고 약간씩 바꿔줘야 함.
Advertisements

리눅스 커맨드로 자바 파일 실행하기

이상한 데서 막혀서 몇 시간을 고생했다;;

리눅스에서 자바 파일을 (ex.채팅 서버)를 실행하려면

a.java 파일(예시) 을 javac로 컴파일하고(즉 a.class라는 클래스 파일로 만들고)

a.class 파일을 java 명령어로 실행하면 된다.

내 경우에는 단순히 컴파일 및 실행이 쉽게 되지 않았는데 단독으로 실행하는 게 아닌 외부 라이브러리 및 다른 클래스들의 의존성이 필요했다.

내가 실행하는 서버와 관련해 3개의 파일을 작성했는데, 여기에다 외부 라이브러리 4개 정도를 사용했다.

우선 컴파일은

javac -cp 라이브러리 파일 주소 :. ChatServer.java

로 컴파일했다. 사이에 :.이 중요하다. 라이브러리 파일 주소 양쪽에 따옴표같은 건 안 했다.

https://stackoverflow.com/questions/18093928/what-does-could-not-find-or-load-main-class-mean?page=1&tab=votes#tab-top

위 글의 첫 번째 답글의 첫 번째 댓글에서 해답을 발견했다.

그리고 실행은 위와 비슷하게

java -cp 라이브러리 파일 주소 :. ChatServer

http://kjk3071.tistory.com/entry/JAVA-javac-%EB%B0%8F-java-%EC%8B%A4%ED%96%89%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD

위 글을 참조했다.

이렇게 보면 참 별 것도 아닌데… 시간 낭비 참 많이 했다.

또한 Error: Could not find or load main class로 시작하는 에러가 계속 발생했는데, 메인 클래스에서 참조하는 나머지 2개 클래스를 찾지 못하는 듯 했다. 그래서 그냥 나머지 클래스들을 메인 클래스 안에 때려 박았더니 됐나? 싶었더니 또 다른 에러가 떴다. 그래서 나머지 클래스 중 하나를 스태틱 클래스로 만들어 주었더니 이제야 된다.

인간은 작은 돌부리에 걸려 넘어진다더니…ㅠ

안드로이드 스튜디오 뒤로가기 두번 클릭 시 메시지 띄우면서 앱 종료하기

java에 다가 아래의 코드 삽입 시 뒤로 버튼 1번 클릭 시 토스트로 메시지 띄워주고

2초 안에 뒤로 버튼 재 클릭 시 앱 종료

//뒤로가기 2번 클릭 시 종료
private long lastTimeBackPressed; //뒤로가기 버튼이 클릭된 시간
@Override
public void onBackPressed()
{
    //2초 이내에 뒤로가기 버튼을 재 클릭 시 앱 종료
    if (System.currentTimeMillis() - lastTimeBackPressed < 2000)
    {
        finish();
        return;
    }
    //'뒤로' 버튼 한번 클릭 시 메시지
    Toast.makeText(this, "'뒤로' 버튼을 한번 더 누르시면 앱이 종료됩니다.", Toast.LENGTH_SHORT).show();
    //lastTimeBackPressed에 '뒤로'버튼이 눌린 시간을 기록
    lastTimeBackPressed = System.currentTimeMillis();
}

출처: http://dove250l.tistory.com/entry/안드로이드-스튜디오-뒤로가기-두번-클릭-시-메시지-띄우면서-앱-종료하기 [dove250l]

안드로이드 클래스에서 액티비티로 데이터 넘기기

인터페이스를 이용하면 된다. 나는 netty 채팅 내용을 서버에서 받아와서 액티비티로 보내 띄울 때 이 작업이 필요했는데, netty chat server와 netty handler를 nettyinitializer가 중간에서 이어주는 형태라서 사이사이에 인터페이스를 2개를 구현해서 연결해 주었다.

출처 : https://stackoverflow.com/questions/34994904/how-to-pass-values-from-a-class-to-activity-android#

 

No toolchains found in the NDK toolchains folder for ABI with prefix: mipsel-linux-android 에러

Find your own local android-sdk, if you download the relevant sdk of ndk, there will be a folder called “ndk-bundle”

image

There is a folder called “toolchains” inside.
image

We noticed that there are no mips64el related files inside.
image

The solution is as follows:

Click here to download the NDK package separately through the browser.
After unzipping, open the “toolchains” folder, compare it with the android-sdk->ndk-bundle->toolchains folder, find the missing folder, copy the past
3. Recompile, the problem is solved.
Hope it helps you mate

출처 : https://github.com/google/filament/issues/15