โชว์วิดีโอใน VideoView จากการอัดวิดีโอจากกล้อง (Camera) และเลือกจากคลังวิดีโอ (Video Gallery)



       สวัสดีครับ  วันนี้ผมจะมาเขียนเกี่ยวกับการโชว์วิดีโอออกมาแสดงใน VideoView นะครับ  ซึ่งบางท่านที่ยังไม่เคยใช้ฟังก์ชั่นตัวนี้ก็อาจจะงง  ว่ามันคืออะไร  VideoView คือ Widget ตัวนึงที่อยู่ในแอนดรอยด์  ทำหน้าที่ในการแสดงวิดีโอ  คล้ายๆกับ ImageView นั้นแหละ  โดยที่จะแสดงวิดีโอออกมาจะมาจากการอัดวิดีโอผ่านทางกล้องมือถือ  และจากการเลือกวิดีโอในคลังวิดีโอ (Video Gallery) ซึ่งถ้าเอาจริงๆ ถามว่ามีฟังก์ชั่นที่ใช้แสดงวิดีโอนอกเหนือจากนี้ไหมก็จะมีเป็น ExoPlayer อีกตัวนึง  ซึ่งตัวนี้ดีมากๆ และถูกรับรองโดยกูเกิล (Google) เรียบร้อย  แต่ว่าในการเขียนโค้ด (Code) ก็เยอะขึ้นด้วยเช่นกัน

       เอาล่ะจะช้าอยู่ไย  ไปดูกันเลยยยยย


 เวอร์ชั่นแอนดรอยด์ที่ใช้

- Phone : Sony Xperia XZ (มือถือของผมเอง)
- compileSdkVersion 26
- minSdkVersion 16   
- targetSdkVersion 26
- versionCode 1

ทำความเข้าใจโค้ดก่อน

       ก่อนจะเข้าไปดูโค้ด (Source Code) มาดูคำอธิบายการทำงานของโค้ดในแต่ละส่วนกันก่อน


    ImageView imageView;
    VideoView vdoView;
    private Uri uri;
    static final int REQUEST_VIDEO_CAPTURE = 1;
    static final int REQUEST_TAKE_GALLERY_VIDEO = 2;
    String pathToStoredVideo;

ก่อนอื่นให้ประกาศตัวแปรในคำสั่งต่างๆ ของตัว Widget ที่ใช้ในการทำงานก่อน ซึ่งก็จะมี ImageView , VideoView , Uri , String  และก็ Int 2 ตัวที่ใช้งานการกำหนดตัวไฟล์รูปมาจากการกล้อง (Camera) หรือเลือกจากคลังวิดีโอ (Gallery)


        vdoView = (VideoView) findViewById(R.id.vdoView);
        imageView = (ImageView) findViewById(R.id.imageView);

       ต่อมาก็ประกาศ VideoView และ ImageView ซึ่งจริงๆ ImageView ในตัวอย่างนี้ผมเอามาไว้ซ้อนหน้า Video เท่านั้นครับ  มันก็คือไอหน้ารูปสามเหลี่ยมปุ่ม Play นั้นแหละ  ซึ่งถ้าใครที่เข้าใจแล้ว  ก็ไม่ต้องใน ImageView ก็ได้นะครับ


final Button btnRecorder = (Button) findViewById(R.id.btnRecorder);
        btnRecorder.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                CharSequence[] items = {"ถ่ายวิดีโอ", "เลือกวิดีโอ"};
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);

                dialog.setTitle("กรุณาเลือกคำสั่ง");
                dialog.setIcon(R.mipmap.ic_launcher_round);
                dialog.setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int item) {
                        if (item == 0) {

                            Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                            if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
                                takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                                startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
                            }

                        } else {

                            Intent intent = new Intent();
                            intent.setType("video/*");
                            intent.setAction(Intent.ACTION_GET_CONTENT);
                            startActivityForResult(Intent.createChooser(intent,"Select Video"),REQUEST_TAKE_GALLERY_VIDEO);
                        }
                    }
                });
                dialog.show();
            }
        });

       โค้ดเริ่มยาวขึ้นล่ะ ฮ่าๆๆ ต่อไปผมได้ทำการประกาศ Button หรือปุ่มกดอัดวิดีโอนั้นเอง  โดยในเงื่อนไหนให้แสดง AlertDialog ออกมาว่าผู้ใช้นั้นสามารถเลือกได้ว่าจะอัดวิดีโอหรือว่าจะเลือกวิดีโอจากคลัง (Gallery)ได้ครับ  โดยตรงฟังก์ชั่น Intent ที่เป็นการเปลี่ยนหน้าไปหน้าอื่นนั้น  ถ้าสังเกตดีๆจะเห็น REQUEST_VIDEO_CAPTURE และ REQUEST_TAKE_GALLERY_VIDEO  ซึ่งเป็น Int 2 ที่จะเป็นตัวที่ชี้ว่าเวลา Intent ไปยังฟังก์ชั่นไหนแล้ว  ให้ส่งค่ากลับมายังไง  โดยที่ในเงื่อนไข if (item == 0) นั้นจะเลือกไปที่กล้องเพื่ออัดวิดีโอ  แล้วส่งวิดีโอกลับมายัง VideoView ส่วนเงื่อนไขที่ 2 else นั้นเป็นการเลือกไฟล์วิดีโอจากในคลัง (Video Gallery) แล้วส่งไฟล์นั้นกลับมายัง VideoView อีกเช่นเคย ดูต่อไป


final Button btnPlay = (Button) findViewById(R.id.btnPlay);
        btnPlay.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                vdoView.setVideoURI(uri);
                vdoView.setMediaController(new MediaController(MainActivity.this));
                vdoView.requestFocus();
                vdoView.start();

                vdoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    public void onPrepared(MediaPlayer mp) {
                        imageView.setVisibility(View.GONE);
                    }
                });
            }
        });

       ต่อมาเป็นปุ่ม btnPlay นะครับหรือว่าปุ่มเล่นวิดีโอนั้นเอง  โดยในเงื่อนไงนี้กำหนดไว้ว่า vdoView.setVideoURI(uri); กำหนด uri ที่เป็นค่าข้อมูลวิดีโอนั้นมาใส่ setMediaController เพื่อให้วิดีโอนั้นมีฟังก์ชั่นการเล่นวิดีโอได้เช่น  การเลื่อนไปหน้าหลัง  กดหยุด เป็นต้น  แล้ว start(); ให้วิดีโอนั้นเล่นได้เลย  สว่นในฟังก์ชัน setOnPreparedListener ก็คือเมื่อวิดีโอเล่นให้รูปภาพ ImageView นั้นหายไป


@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == Activity.RESULT_OK && requestCode == REQUEST_VIDEO_CAPTURE){
            uri = data.getData();
            vdoView.setVideoURI(uri);

            pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this);
            Log.i("Test" , pathToStoredVideo);

        } else if (requestCode == REQUEST_TAKE_GALLERY_VIDEO && resultCode == RESULT_OK) {

            uri = data.getData();
            vdoView.setVideoURI(uri);

            pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this);
            Log.i("Test",  pathToStoredVideo);
            
        }
    }

    private String getRealPathFromURIPath(Uri uri, MainActivity mainActivity) {

        String generatedFilename = String.valueOf(System.currentTimeMillis());
        String filePathEnvironment = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
        File directoryFolder = new File(filePathEnvironment + "/video/");
        if(!directoryFolder.exists()){
            directoryFolder.mkdir();
        }
        return filePathEnvironment + "/video/" + generatedFilename + ".mp4";
    }


       ต่อมาเป็นส่วนของ onActivityResult ครับ  ส่วนนี้แหละสำคัญ  เพราะส่วนนี้เป็นส่วนที่รับค่ามาจาก Intent ก่อนหน้านี้นั้นเอง  จากนั้นก็วางเงื่อนไข if else ไว้  โดยที่ใน if ด้านบนจะเป็นรับค่ามาจากการอัดวิดีโอ  และในส่วนของ else if รับค่ามาจากการเลือกไฟล์วิดีโอ  แล้วเราก็ทำการ setVideoURI เพื่อใส่ข้อมูลลงใน VideoView แล้วก็ด้านล่างก็ประกาศ getRealPathFromURIPath ไว้  เพื่อเอาดึง Path วิดีโอนั้นๆออกมาได้  เอาไว้สำหรับนำไปประยุกงานต่อๆไป 


vdoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.setLooping(true);
                }
            });

       แล้วก็ถ้าอยากให้วิดีโอเล่นไปเรื่อยๆ ไม่ต้องหยุดก็ใส่โค้ดนี้เข้าไปนะครับ  วิดีโอเล่นจบมันก็จะเริ่มใหม่  แล้วก็เล่นต่อไปเรื่อยๆๆๆ แต่กินแบตน่าดู 555  จบไปดูโค้ดทั้งหมดเถอะ

โค้ดทั้งหมด

ไฟล์ XML : activity_main.xml

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tableLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Camera Recorder Videos"
            android:layout_span="1"
            android:textAppearance="?android:attr/textAppearanceLarge" />

    </TableRow>

    <View
        android:layout_height="1dip"
        android:background="#CCCCCC" />

    <TableLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.1"
        android:orientation="horizontal"
        android:gravity="center">

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.1"
            android:gravity="center">

            <VideoView
                android:id="@+id/vdoView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0.64" />

            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:layout_alignEnd="@+id/vdoView"
                android:src="@mipmap/ic_play_video"
                android:layout_alignRight="@+id/vdoView" />

        </RelativeLayout>

        <Button
            android:id="@+id/btnRecorder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Camera Recorder" />

        <Button
            android:id="@+id/btnPlay"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Play" />

    </TableLayout>

    <View
        android:layout_height="1dip"
        android:background="#CCCCCC" />

</TableLayout>
อันนี้เอามาจาก Thaicreate นะครับ

ไฟล์ Java : MainActivity.java

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.VideoView;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    VideoView vdoView;
    private Uri uri;
    static final int REQUEST_VIDEO_CAPTURE = 1;
    static final int REQUEST_TAKE_GALLERY_VIDEO = 2;
    String pathToStoredVideo;

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

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        vdoView = (VideoView) findViewById(R.id.vdoView);
        imageView = (ImageView) findViewById(R.id.imageView);

        // *** Camera Recorder
        final Button btnRecorder = (Button) findViewById(R.id.btnRecorder);
        btnRecorder.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                CharSequence[] items = {"ถ่ายวิดีโอ", "เลือกวิดีโอ"};
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);

                dialog.setTitle("กรุณาเลือกคำสั่ง");
                dialog.setIcon(R.mipmap.ic_launcher_round);
                dialog.setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int item) {
                        if (item == 0) {

                            Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                            if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
                                takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                                startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
                            }

                        } else {

                            Intent intent = new Intent();
                            intent.setType("video/*");
                            intent.setAction(Intent.ACTION_GET_CONTENT);
                            startActivityForResult(Intent.createChooser(intent,"Select Video"),REQUEST_TAKE_GALLERY_VIDEO);
                        }
                    }
                });
                dialog.show();
            }
        });

        final Button btnPlay = (Button) findViewById(R.id.btnPlay);
        btnPlay.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                vdoView.setVideoURI(uri);
                vdoView.setMediaController(new MediaController(MainActivity.this));
                vdoView.requestFocus();
                vdoView.start();

                vdoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    public void onPrepared(MediaPlayer mp) {
                        imageView.setVisibility(View.GONE);
                    }
                });
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == Activity.RESULT_OK && requestCode == REQUEST_VIDEO_CAPTURE){
            uri = data.getData();
            vdoView.setVideoURI(uri);

            pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this);
            Log.i("Test" , pathToStoredVideo);

        } else if (requestCode == REQUEST_TAKE_GALLERY_VIDEO && resultCode == RESULT_OK) {

            uri = data.getData();
            vdoView.setVideoURI(uri);

            pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this);
            Log.i("Test",  pathToStoredVideo);
            
        }
    }

    private String getRealPathFromURIPath(Uri uri, MainActivity mainActivity) {

        String generatedFilename = String.valueOf(System.currentTimeMillis());
        String filePathEnvironment = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
        File directoryFolder = new File(filePathEnvironment + "/video/");
        if(!directoryFolder.exists()){
            directoryFolder.mkdir();
        }
        return filePathEnvironment + "/video/" + generatedFilename + ".mp4";
    }
}
ไฟล์โค้ด Java ทั้งหมด

       เป็นยังไงกันบ้างครับ  สำหรับตัวอย่างนี้  "โชว์วิดีโอใน VideoView จากการอัดวิดีโอจากกล้อง (Camera) และเลือกจากคลังวิดีโอ (Video Gallery)" ไม่ยากเลยใช่ไหมครับ  ซึ่งจริงๆตัวอย่างนี้สามารถทำเอาไปประยุกต์ใช้งานได้เยอะนะครับ  หลายงานเลยที่เกี่ยวกับวิดีโอ  เด่วจะทำของรูปด้วยรอแปป  แล้วก็ถ้าใครที่ยังทำไม่ได้มี Source Code ให้ดาวโหลดไปทำกันนะครับ

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

การรับค่า ส่งค่าจากหน้าที่ 1 ไปหน้าที่ 2 บน Flutter (How to pass data between screens in Flutter?)

การจับเวลาบน Flutter ทำยังไง (How to count up timer flutter?)

วิธีการสลับข้อมูล MySQL ในคอลัมน์เดียวกัน