开发者

Video doesn't launch and JPEG no longer displays when code added

Hi All Real beginner here on Android. I am writing an app that displays a full screen jpg that has a file that is read that has touch areas defined on a granularity of 20 x 20 pixels. These touch areas are decoded to videos to play. The jpg and touch area decode work just fine, until I un comment out play_video(), then the emulator just displays a blank screen and hangs. The possible video numbers are 0 through 7 with 8 being used to indicate a non valid touch.

I am pulling what remains of my hair out over this.

Here is the java code

package org.example.video_4;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.ImageView;

public class video_4 extends Activity {
    byte[] videos_to_play = new byte[960];
    boolean video_playing = false;
    int video_to_play = 8;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        // now display the adBook background screen this is a full screen
        // due to the declaration in manifest.xml under activity
        // android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
        setContentView(R.layout.main);
        ImageView jpgView = (ImageView) findViewById(R.id.jpgview);
        String myJpgPath = "/sdcard/AdBook.JPG"; //UPDATE WITH YOUR OWN JPG FILE
        Bitma开发者_运维知识库pFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 1;
        Bitmap bm = BitmapFactory.decodeFile(myJpgPath, options);
        jpgView.setImageBitmap(bm);
        // now we have to wait for a touch and then fire of the video play
        // we also return here when the video is complete so as we wait for
        // touch demand for a video to play
        set_touch_areas();

        /*******************************************************
         Problem area all works fine until I uncomment this code
         ********************************************************/

        /* play_video();*/
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int xpos, ypos;

        if (event.getAction() != MotionEvent.ACTION_DOWN) {
            return super.onTouchEvent(event);
        }
        xpos = (int) event.getX() / 20;
        ypos = (int) event.getY() / 20;
        if (xpos < 0 || xpos > 39 || ypos < 0 || ypos > 23) {
            video_to_play = 8;
            return true;
        }
        video_to_play = videos_to_play[(ypos * 40) + xpos];
        return true;
    }

    public void set_touch_areas() {
        // read in the touch file
        File file = new File("/sdcard/adbook.tch");
        FileInputStream is;
        int c, v, x;

        try {
            is = new FileInputStream(file);

            // Get the size of the file
            long length = file.length();
            if (length != 960) {
                finish();
            }
            // Read in the bytes
            int offset = 0;
            int numRead = 0;
            while (offset < videos_to_play.length && (numRead = is.read(videos_to_play, offset, videos_to_play.length - offset)) >= 0) {
                offset += numRead;
            }
            // Ensure all the bytes have been read in
            if (offset < videos_to_play.length) {
                finish();
            }
        } catch (FileNotFoundException e1) {
            // just bomb if anything is bad with the file read
            finish();
        } catch (IOException e) {
            // just bomb if anything is bad with the file read
            finish();
        }
        // we have read the adbook.tch file so now decode the entries based
        // on my algorithm of invert, valid & video_num / random data
        for (c = 0; c < 960; c++) {
            v = (videos_to_play[c] & 0xc0) >> 6; // mask and align the bits for checking
            if (v == 0x02) { // inverted and video valid
                x = videos_to_play[c]; // java can only invert integer
                x = ~x; // so invert an integer, what a pain!!
                videos_to_play[c] = (byte)(x & 0x07); // mask to the valid number
            } else if (v == 0x01) { // non inverted and video valid
                videos_to_play[c] &= (byte) 0x07; // so just isolate the video number
            } else { // non valid entry who cares,  I do
                videos_to_play[c] = (byte) 0x08; // it's not valid so store the fact
            }
        }
    }

    public void play_video() {
        String myMp4Path = "/sdcard/v1.mp4";

        video_to_play = 8;
        while (true) {
            if ((video_to_play < 8) && (video_playing == false)) {
                switch (video_to_play) {
                case 0:
                    myMp4Path = "/sdcard/v0.mp4";
                    break;
                case 1:
                    myMp4Path = "/sdcard/v1.mp4";
                    break;
                case 2:
                    myMp4Path = "/sdcard/v2.mp4";
                    break;
                case 3:
                    myMp4Path = "/sdcard/v3.mp4";
                    break;
                case 4:
                    myMp4Path = "/sdcard/v4.mp4";
                    break;
                case 5:
                    myMp4Path = "/sdcard/v5.mp4";
                    break;
                case 6:
                    myMp4Path = "/sdcard/v6.mp4";
                    break;
                case 7:
                    myMp4Path = "/sdcard/v7.mp4";
                    break;
                default:
                    myMp4Path = "/sdcard/v4.mp4";
                    break;
                }
                video_playing = true;
                MediaPlayer mp = new MediaPlayer();
                try {
                    mp.setDataSource(myMp4Path);
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    mp.prepare();
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                mp.start();
                while (mp.isPlaying());
                video_playing = false;
                video_to_play = 8;
            }
        }
    }
}


It appears that your play_video() will not return until the end of the video

while (mp.isPlaying());

yet you call this from onCreate(). onCreate runs on the UI thread and so must return very quickly or the application will be unresponsive - some of the things you have requested may not even begin to occur until after onCreate() returns. You need to start the video and then return. Set up other events to activate on its completion, or have a separate thread that monitors it.


If I am not wrong,

    video_to_play = 8;
    while (true) {
        if ((video_to_play < 8) && (video_playing == false)) {

video_to_play is always 8, so it will never play a Video other than /sdcard/v1.mp4

If you set this variable for testing your app, you should have removed the swith()-Statement in the posting of your Question.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜