Android-Exoplayer 2-流畅地更换重叠音乐

Android-Exoplayer 2-流畅地更换重叠音乐,android,exoplayer2.x,Android,Exoplayer2.x,我正在用Exoplayer 2构建一个音乐播放器。 我想以平稳的方式改变音乐,两种音乐重叠。因此,当您转到下一首歌时,当前一首歌会变暗,而第二首歌会启动 我不明白Exoplayer如何能同时播放两种声音 PS:我无法创建唯一的合并音乐,因为我事先不知道音乐何时通过。如下所述,似乎还不支持此功能(交叉衰落)。请查看下面的链接 来源: 但是,如果您可以牺牲重叠功能,您可以将其作为一种解决方法,如上面链接中所述,在最后N秒减少上一首音乐的声音,并在上一首音乐结束后增加声音,启动其他音乐。它不会同时,,

我正在用Exoplayer 2构建一个音乐播放器。 我想以平稳的方式改变音乐,两种音乐重叠。因此,当您转到下一首歌时,当前一首歌会变暗,而第二首歌会启动

我不明白Exoplayer如何能同时播放两种声音


PS:我无法创建唯一的合并音乐,因为我事先不知道音乐何时通过。

如下所述,似乎还不支持此功能(交叉衰落)。请查看下面的链接

来源

但是,如果您可以牺牲重叠功能,您可以将其作为一种解决方法,如上面链接中所述,在最后N秒减少上一首音乐的声音,并在上一首音乐结束后增加声音,启动其他音乐。它不会同时,而是按顺序

请参见下文:(这些当然只是一个示例/示例代码部分,旨在提供有关解决方案的想法,可能还有另一种/更好的方法来实现此解决方案。尽管考虑了某些情况,但仍可能有一些遗漏或错误。因此,可以自由修改)

在减少声音的同时完成以前的音乐,在增加声音的同时开始新音乐

Target decreaseVolumeTarget = new Target() {
  @Override
  void handleMessage(int messageType, Object payload) throws ExoPlaybackException {
    Integer[] payloadArr = (Integer[]) payload;
    Integer volumeAmount = payloadArr[0];
    Integer dontExceedVolumeAmount = payloadArr[1];

    float playerVolume = player.getVolume() * 100.0F;

    /* Decrease if playerVolume is bigger than 0 */
    if(playerVolume > 0) {
      /* If the player volume is bigger than the target volume */
      if(playerVolume > dontExceedVolumeAmount) {
        /* If volumeAmount is bigger than the volume difference between player & target */
        if(playerVolume - dontExceedVolumeAmount < volumeAmount) {
          volumeAmount = playerVolume - dontExceedVolumeAmount;
        }

        playerVolume = playerVolume - volumeAmount; /* 100% to 0% */
        player.setVolume(playerVolume / 100.0F);

        volumeDecreaseOperationDone = true;
      }
    }     
  }
}

Target increaseVolumeTarget = new Target() {
  @Override
  void handleMessage(int messageType, Object payload) throws ExoPlaybackException {
    Integer[] payloadArr = (Integer[]) payload;
    Integer volumeAmount = payloadArr[0];
    Integer dontExceedVolumeAmount = payloadArr[1];

    float playerVolume = player.getVolume() * 100.0F;

    /* Increase if playerVolume is smaller than 100 */
    if(playerVolume < 100) {
      /* If the player volume is lower than the target volume */
      if(playerVolume < dontExceedVolumeAmount) {
        /* If volumeAmount is bigger than the volume difference between player & target */
        if(dontExceedVolumeAmount - playerVolume < volumeAmount) {
          volumeAmount = dontExceedVolumeAmount - playerVolume;
        }

        // Consider the original user set volume
        if(initialPlayerVolume - playerVolume < volumeAmount) {
          volumeAmount = initialPlayerVolume - playerVolume;
        }

        playerVolume = playerVolume + volumeAmount; /* 0% to 100% */
        player.setVolume(playerVolume / 100.0F);

        volumeIncreaseOperationDone = true;
      }
    }
  }
}

如下所述,似乎还不支持此功能(交叉衰落)。请查看下面的链接

来源

但是,如果您可以牺牲重叠功能,您可以将其作为一种解决方法,如上面链接中所述,在最后N秒减少上一首音乐的声音,并在上一首音乐结束后增加声音,启动其他音乐。它不会同时,而是按顺序

请参见下文:(这些当然只是一个示例/示例代码部分,旨在提供有关解决方案的想法,可能还有另一种/更好的方法来实现此解决方案。尽管考虑了某些情况,但仍可能有一些遗漏或错误。因此,可以自由修改)

在减少声音的同时完成以前的音乐,在增加声音的同时开始新音乐

Target decreaseVolumeTarget = new Target() {
  @Override
  void handleMessage(int messageType, Object payload) throws ExoPlaybackException {
    Integer[] payloadArr = (Integer[]) payload;
    Integer volumeAmount = payloadArr[0];
    Integer dontExceedVolumeAmount = payloadArr[1];

    float playerVolume = player.getVolume() * 100.0F;

    /* Decrease if playerVolume is bigger than 0 */
    if(playerVolume > 0) {
      /* If the player volume is bigger than the target volume */
      if(playerVolume > dontExceedVolumeAmount) {
        /* If volumeAmount is bigger than the volume difference between player & target */
        if(playerVolume - dontExceedVolumeAmount < volumeAmount) {
          volumeAmount = playerVolume - dontExceedVolumeAmount;
        }

        playerVolume = playerVolume - volumeAmount; /* 100% to 0% */
        player.setVolume(playerVolume / 100.0F);

        volumeDecreaseOperationDone = true;
      }
    }     
  }
}

Target increaseVolumeTarget = new Target() {
  @Override
  void handleMessage(int messageType, Object payload) throws ExoPlaybackException {
    Integer[] payloadArr = (Integer[]) payload;
    Integer volumeAmount = payloadArr[0];
    Integer dontExceedVolumeAmount = payloadArr[1];

    float playerVolume = player.getVolume() * 100.0F;

    /* Increase if playerVolume is smaller than 100 */
    if(playerVolume < 100) {
      /* If the player volume is lower than the target volume */
      if(playerVolume < dontExceedVolumeAmount) {
        /* If volumeAmount is bigger than the volume difference between player & target */
        if(dontExceedVolumeAmount - playerVolume < volumeAmount) {
          volumeAmount = dontExceedVolumeAmount - playerVolume;
        }

        // Consider the original user set volume
        if(initialPlayerVolume - playerVolume < volumeAmount) {
          volumeAmount = initialPlayerVolume - playerVolume;
        }

        playerVolume = playerVolume + volumeAmount; /* 0% to 100% */
        player.setVolume(playerVolume / 100.0F);

        volumeIncreaseOperationDone = true;
      }
    }
  }
}

您好,我已使用此github演示创建了小演示帮助查看此it me帮助您解决问题。您好,我已使用此github演示创建了小演示帮助查看此it me帮助您解决问题。
@Override
public void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) {
  //Get new track information & increase volume slowly    

  switch (reason) {
    case Player.DISCONTINUITY_REASON_PERIOD_TRANSITION:
      // Get new track duration
      long trackDuration = player.getDuration();

      if(volumeDecreaseOperationDone){
        volumeDecreaseOperationDone = false;

        // Check track duration whether it is longer than 1000 ms or not before sending message
        if(trackDuration > 1000) {
          player.createMessage(increaseVolumeTarget)
          .setPosition(1000L) // in milliseconds
          .setPayload(new Integer[]{ 20, 20 })
          .setHandler(new Handler()) // A shared handler may also be used
          .send();
        }

        // Check track duration whether it is longer than 2000 ms or not before sending message
        if(trackDuration > 2000) {
          player.createMessage(increaseVolumeTarget)
          .setPosition(2000L) // in milliseconds
          .setPayload(new Integer[]{ 20, 40 })
          .setHandler(new Handler()) // A shared handler may also be used
          .send();
        }

        // Check track duration whether it is longer than 3000 ms or not before sending message
        if(trackDuration > 3000) {
          player.createMessage(increaseVolumeTarget)
          .setPosition(3000L) // in milliseconds
          .setPayload(new Integer[]{ 20, 60 })
          .setHandler(new Handler()) // A shared handler may also be used
          .send();
        }

        // Check track duration whether it is longer than 4000 ms or not before sending message
        if(trackDuration > 4000) {
          player.createMessage(increaseVolumeTarget)
          .setPosition(4000L) // in milliseconds
          .setPayload(new Integer[]{ 20, 80 })
          .setHandler(new Handler()) // A shared handler may also be used
          .send();
        }

        // Check track duration whether it is longer than 5000 ms or not before sending message
        if(trackDuration > 5000) {
          player.createMessage(increaseVolumeTarget)
          .setPosition(5000L) // in milliseconds
          .setPayload(new Integer[]{ 20, 100 })
          .setHandler(new Handler()) // A shared handler may also be used
          .send();
        }
      }
      break;
    case Player.DISCONTINUITY_REASON_SEEK:
      break;
    case Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT:         
      break;
    case Player.DISCONTINUITY_REASON_AD_INSERTION:        
      break;
    case Player.DISCONTINUITY_REASON_INTERNAL:         
      break;
  }

}