处理中的交互式视频播放器

时间:2015-11-21 17:25:55

标签: processing interactive video-player

我们正在尝试创建一个包含10个短视频文件的交互式视频播放器,但它必须具有某种功能:第一个视频从头开始自动播放。一旦完成,用户必须通过箭头点击选择,接下来要播放哪个视频 - 有两个选项。一旦选择完视频选项,下一个视频必须自动开始播放。完成此视频播放后,必须在另外两个视频之间进行另一个选择,就像第一次一样,然后继续播放,直到第10个视频播放结束为止。

有两个主要问题 - 在第一个视频播放和第一个选择完成后,第三个视频,假设自动播放,不播放,整个应用程序卡住。此外,在播放第一个默认视频时,按下的按键会触发其他两个视频播放,同时他们认为只有在第一个视频播放完毕后才能播放。 为了使其更容易理解,视频播放顺序和交互点的结构,这里是它的例证:

Interactive video player structure

我们希望我们能够制定问题,因此很容易理解。任何帮助或提示将受到高度赞赏。

import processing.video.*;

Movie [] mov = new Movie [10];

Boolean playMovie0 = true;
Boolean playMovie1 = false;
Boolean playMovie2 = false;
Boolean playMovie3 = false;
Boolean playMovie4 = false;
Boolean playMovie5 = false;
Boolean playMovie6 = false;
Boolean playMovie7 = false;
Boolean playMovie8 = false;
Boolean playMovie9 = false;

void setup (){
  size (810, 540);

  mov [0] = new Movie (this, "Vid0.mp4");
  mov [1] = new Movie (this, "Vid1.mp4");
  mov [2] = new Movie (this, "Vid2.mp4");
  mov [3] = new Movie (this, "Vid3.mp4");
  mov [4] = new Movie (this, "Vid4.mp4");
  mov [5] = new Movie (this, "Vid5.mp4");
  mov [6] = new Movie (this, "Vid6.mp4");
  mov [7] = new Movie (this, "Vid7.mp4");
  mov [8] = new Movie (this, "Vid8.mp4");
  mov [9] = new Movie (this, "Vid9.mp4");

  mov[0].play();
}

void draw (){
  if (playMovie0 == true){
    image(mov[0], 0, 0, width, height);

    if (mov[0].time() >= mov[0].duration()){
      mov[0].stop();
      playMovie0 =false;
    }
    if (key == CODED){
      if (keyCode == LEFT){
        playMovie1 = true;
        mov[1].play();
        image(mov[1], 0, 0, width, height);
      } else if (keyCode == RIGHT){
        playMovie2 = true;
        mov[2].play();
        image(mov[2], 0, 0, width, height);
      }
    }
  }

  if (mov[1].time() >= mov[1].duration()){
    mov[1].stop();
    playMovie1 = false;
    playMovie3 = true;
  } else if (mov[2].time() >= mov[2].duration()){
    mov[2].stop();
    playMovie2 = false;
    playMovie3 = true;
  }

  if (playMovie0 == false && playMovie1 == false && playMovie2 == false && playMovie3 == true){
    mov[3].play();
    image(mov[3], 0, 0, width, height);

    if (mov[3].time() >= mov[3].duration()){
      mov[3].stop();
      playMovie3 = false;
    }

    if (key == CODED){
      if (keyCode == LEFT){
        playMovie4 = true;
        mov[4].play();
        image(mov[4], 0, 0, width, height);
      } else if (keyCode == RIGHT){
        playMovie5 = true;
        mov[5].play();
        image(mov[5], 0, 0, width, height);
      }
    }
  }

  if (mov[4].time() >= mov[4].duration()){
    mov[4].stop();
    playMovie4 = false;
    playMovie6 = true;
  } else if (mov[5].time() >= mov[5].duration()){
    mov[5].stop();
    playMovie5 = false;
    playMovie6 = true;
  }

  if (playMovie0 == false && playMovie1 == false && playMovie2 == false &&
    playMovie3 == false && playMovie4 == false && playMovie5 == false && playMovie6 == true) {

    mov[6].play();
    image(mov[6], 0, 0, width, height);

    if (mov[6].time() >= mov[6].duration()){
      mov[6].stop();
      playMovie6 = false;
    }

    if (key == CODED){
      if (keyCode == LEFT){
        playMovie7 = true;
        mov[7].play();
        image(mov[7], 0, 0, width, height);
      } else if (keyCode == RIGHT){
        playMovie8 = true;
        mov[8].play();
        image(mov[8], 0, 0, width, height);
      }
    }
  }

  if (mov[7].time() >= mov[7].duration()){
    mov[7].stop();
    playMovie7 = false;
    playMovie9 = true;
  } else if (mov[8].time() >= mov[8].duration()){
    mov[8].stop();
    playMovie8 = false;
    playMovie9 = true;
  }

  if (playMovie0 == false && playMovie1 == false && playMovie2 == false &&
    playMovie3 == false && playMovie4 == false && playMovie5 == false &&
    playMovie6 == false && playMovie7 == false && playMovie8 == false && playMovie9 == true){

    mov[9].play();
    image(mov[9], 0, 0, width, height);
  }
}

void movieEvent (Movie m)
{
  m.read();
}

1 个答案:

答案 0 :(得分:0)

请仔细阅读有关播放视频列表主题的this similar answer。它涵盖了一些方便的技巧,例如不重复自己和使用数组。

使你的问题与众不同的唯一部分是管理状态,目前至少为3:

  1. 播放自动视频
  2. 展示下一个视频选择屏幕
  3. 播放所选视频
  4. 这些状态会一直交替,直到达到播放列表的末尾。 这被称为finite state machine并且使得一个人看起来并不那么难。有一些'成分'你需要:

    1. 用于跟踪当前状态的变量
    2. 每个单独州的变量列表;
    3. 获得这些后,您只需要检查当前状态是什么,并根据此状态下可用的决策,选择下一个。

      例如,在自动视频播放中,可以在视频结尾处做出决定:

      • 是最后一个视频
      • 如果没有,请转到选择屏幕

      在选择屏幕上,决定基于键输入:

      • 如果按下左键,则播放下一个视频
      • 如果按下右键,则在当前
      • 之后播放第二个视频

      等等。

      以下是代码的概念,其中的注释解释了每个部分:

      import processing.video.*;
      
      int numMovies = 10;//total number of movies
      Movie [] mov = new Movie [numMovies];//a list of all the movie objects, currently not initialized
      
      int currentMovieIndex = 0;//index of the movie currently playing
      int movieIndexOffset;//the offset in index between the selected/automatic movies (skip 1 or 2 videos?)
      
      //application states
      int STATE_WAITING_FOR_KEY = 0;
      int STATE_PLAYING_SELECTED_MOVIE = 1;
      int STATE_PLAYING_AUTOMATIC_MOVIE = 2;
      
      int currentState = STATE_PLAYING_AUTOMATIC_MOVIE;
      //just for debugging:
      String[] stateLabels = {"waiting for key","playing selected movie","playing automatic movie"};
      
      //a 'magic number' helpful to find out when a movie finishes playing
      float movieEndDuration = 0.039719;
      
      String selectScreenText = "Use the left or right keys to select the next video";
      
      
      void setup (){
        size (810, 540);
        noStroke();
        textSize(24);
      
        for(int i = 0 ; i < numMovies; i++){
          //initialize each movie object in the list
          mov[i] = new Movie(this, "vid"+i+".mp4");
        }
      
        //start playback
        mov[currentMovieIndex].play();
      }
      
      void draw (){
        if(currentState == STATE_WAITING_FOR_KEY) drawWaitKeyState();
        if(currentState == STATE_PLAYING_AUTOMATIC_MOVIE || 
           currentState == STATE_PLAYING_SELECTED_MOVIE) drawMovie();
      }
      //rendering
      void drawWaitKeyState(){
        background(0);
        text(selectScreenText,(width-textWidth(selectScreenText)) * 0.5,height * 0.5);  
      }
      void drawMovie(){
        background(0);
        image(mov[currentMovieIndex],0,0);
      }
      //events
      void keyReleased(){
        if(currentState == STATE_WAITING_FOR_KEY){
          if(keyCode == LEFT)  {
            movieIndexOffset = 1;//current movie index plus 1
            playSelectedMovie();
          }
          if(keyCode == RIGHT) {
            movieIndexOffset = 2;//current movie index plus 2
            playSelectedMovie();//current movie index plus 2
          }
        }
      }
      /*
        A - auto
        S - selected
        movie index type: A - S - A - S - A - S - A
        movie index:      0 - 1 - 3 - 4 - 6 - 7 - 9
                            - 2 /     5 /   - 8 / 
      */
      void playSelectedMovie(){
        currentState = STATE_PLAYING_SELECTED_MOVIE;
        currentMovieIndex += movieIndexOffset;
        mov[currentMovieIndex].play();
        println("selection made, playing movie at index " + currentMovieIndex);
      }
      void movieEvent (Movie m)
      {
        if(currentState == STATE_PLAYING_AUTOMATIC_MOVIE || currentState == STATE_PLAYING_SELECTED_MOVIE){
          m.read();
          //handy for debugging movie end
      //    println(m.time() + " / " + m.duration() + " / " + (m.time() + movieEndDuration));
          //hacky check movie end 
          if((m.time() + movieEndDuration) >= m.duration()){
              println("movie at index " + currentMovieIndex + " finished playback, current state: " + stateLabels[currentState]);
      
              //if the current state is an automatic video, the next state will be a choice screen
              if(currentState == STATE_PLAYING_AUTOMATIC_MOVIE) {
                //if it's not the last movie
                if(currentMovieIndex < numMovies-1){
                  currentState = STATE_WAITING_FOR_KEY;
                }else{
                  println("all movies finished playing, either reset to first movie or set an end screen");
                }
              }
              //if the current state is a selected video, the next state will be an automatic video
              if(currentState == STATE_PLAYING_SELECTED_MOVIE) {
                currentState = STATE_PLAYING_AUTOMATIC_MOVIE;
                //reverse 1 or 2 by subtracting from 3 
                //if the previous choice was to skip 2, automatically skip 1 ( 3 - 2 = 1), if the previous choice was to skip 1, automatically skip 2 ( 3 - 1 = 2) 
                int automaticOffset = 3 - movieIndexOffset; 
                currentMovieIndex += automaticOffset;
                mov[currentMovieIndex].play();
                println("automatically playing movie at index " + currentMovieIndex);
              }
          }
        }
      }