提交 4633a6aa 编写于 作者: G guoshuyu

去除view层带IMediaPlayer的应用

上级 d501d5c9
......@@ -123,7 +123,7 @@ public class WebDetailActivity extends GSYBaseActivityDetail<StandardGSYVideoPla
@Override
public GSYVideoOptionBuilder getGSYVideoOptionBuilder() {
String url = "https://res.exexm.com/cw_145225549855002";
String url = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4";
//String url = "https://d131x7vzzf85jg.cloudfront.net/upload/documents/paper/b2/61/00/00/20160420_115018_b544.mp4";
//增加封面。内置封面可参考SampleCoverVideo
ImageView imageView = new ImageView(this);
......
......@@ -143,4 +143,89 @@ public class GSYExoPlayerManager implements IPlayerManager {
public void setSpeedPlaying(float speed, boolean soundTouch) {
}
@Override
public void start() {
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
@Override
public void stop() {
if (mediaPlayer != null) {
mediaPlayer.stop();
}
}
@Override
public void pause() {
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
@Override
public int getVideoWidth() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoWidth();
}
return 0;
}
@Override
public int getVideoHeight() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoHeight();
}
return 0;
}
@Override
public boolean isPlaying() {
if (mediaPlayer != null) {
return mediaPlayer.isPlaying();
}
return false;
}
@Override
public void seekTo(long time) {
if (mediaPlayer != null) {
mediaPlayer.seekTo(time);
}
}
@Override
public long getCurrentPosition() {
if (mediaPlayer != null) {
return mediaPlayer.getCurrentPosition();
}
return 0;
}
@Override
public long getDuration() {
if (mediaPlayer != null) {
return mediaPlayer.getDuration();
}
return 0;
}
@Override
public int getVideoSarNum() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarNum();
}
return 1;
}
@Override
public int getVideoSarDen() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarDen();
}
return 1;
}
}
......@@ -316,8 +316,7 @@ public class DanmakuVideoPlayer extends StandardGSYVideoPlayer {
* 弹幕偏移
*/
private void resolveDanmakuSeek(DanmakuVideoPlayer gsyVideoPlayer, long time) {
if (getGSYVideoManager().getMediaPlayer() != null && mHadPlay
&& gsyVideoPlayer.getDanmakuView() != null && gsyVideoPlayer.getDanmakuView().isPrepared()) {
if (mHadPlay && gsyVideoPlayer.getDanmakuView() != null && gsyVideoPlayer.getDanmakuView().isPrepared()) {
gsyVideoPlayer.getDanmakuView().seekTo(time);
}
}
......
......@@ -84,8 +84,7 @@ public class PreViewGSYVideoPlayer extends NormalGSYVideoPlayer {
layoutParams.leftMargin = offset;
//设置帧预览图的显示位置
mPreviewLayout.setLayoutParams(layoutParams);
if (getGSYVideoManager().getMediaPlayer() != null
&& mHadPlay && (mOpenPreView)) {
if (mHadPlay && mOpenPreView) {
mPreProgress = progress;
}
}
......
......@@ -331,8 +331,7 @@ public class SampleVideo extends StandardGSYVideoPlayer {
final String name = mUrlList.get(position).getName();
if (mSourcePosition != position) {
if ((mCurrentState == GSYVideoPlayer.CURRENT_STATE_PLAYING
|| mCurrentState == GSYVideoPlayer.CURRENT_STATE_PAUSE)
&& getGSYVideoManager().getMediaPlayer() != null) {
|| mCurrentState == GSYVideoPlayer.CURRENT_STATE_PAUSE)) {
final String url = mUrlList.get(position).getUrl();
onVideoPause();
final long currentPosition = mCurrentPosition;
......
......@@ -198,8 +198,8 @@ public class SmartPickVideo extends StandardGSYVideoPlayer {
@Override
public void onPrepared() {
if (mTmpManager != null) {
mTmpManager.getMediaPlayer().start();
mTmpManager.getMediaPlayer().seekTo(getCurrentPositionWhenPlaying());
mTmpManager.start();
mTmpManager.seekTo(getCurrentPositionWhenPlaying());
}
}
......@@ -281,8 +281,7 @@ public class SmartPickVideo extends StandardGSYVideoPlayer {
final String name = mUrlList.get(position).getName();
if (mSourcePosition != position) {
if ((mCurrentState == GSYVideoPlayer.CURRENT_STATE_PLAYING
|| mCurrentState == GSYVideoPlayer.CURRENT_STATE_PAUSE)
&& GSYVideoManager.instance().getMediaPlayer() != null) {
|| mCurrentState == GSYVideoPlayer.CURRENT_STATE_PAUSE)) {
showLoading();
final String url = mUrlList.get(position).getUrl();
cancelProgressTimer();
......
......@@ -345,14 +345,6 @@ public abstract class GSYVideoBaseManager implements IMediaPlayer.OnPreparedList
bufferPoint = percentsAvailable;
}
@Override
public IMediaPlayer getMediaPlayer() {
if (playerManager != null) {
return playerManager.getMediaPlayer();
}
return null;
}
@Override
public int getLastState() {
return lastState;
......@@ -447,6 +439,100 @@ public abstract class GSYVideoBaseManager implements IMediaPlayer.OnPreparedList
}
}
@Override
public IPlayerManager getPlayer() {
return playerManager;
}
@Override
public void start() {
if (playerManager != null) {
playerManager.start();
}
}
@Override
public void stop() {
if (playerManager != null) {
playerManager.stop();
}
}
@Override
public void pause() {
if (playerManager != null) {
playerManager.pause();
}
}
@Override
public int getVideoWidth() {
if (playerManager != null) {
return playerManager.getVideoWidth();
}
return 0;
}
@Override
public int getVideoHeight() {
if (playerManager != null) {
return playerManager.getVideoHeight();
}
return 0;
}
@Override
public boolean isPlaying() {
if (playerManager != null) {
return playerManager.isPlaying();
}
return false;
}
@Override
public void seekTo(long time) {
if (playerManager != null) {
playerManager.seekTo(time);
}
}
@Override
public long getCurrentPosition() {
if (playerManager != null) {
return playerManager.getCurrentPosition();
}
return 0;
}
@Override
public long getDuration() {
if (playerManager != null) {
return playerManager.getDuration();
}
return 0;
}
@Override
public int getVideoSarNum() {
if (playerManager != null) {
return playerManager.getVideoSarNum();
}
return 0;
}
@Override
public int getVideoSarDen() {
if (playerManager != null) {
return playerManager.getVideoSarDen();
}
return 0;
}
@Override
public int getRotateInfoFlag() {
return IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED;
}
protected void sendMessage(Message message) {
mMediaHandler.sendMessage(message);
}
......
......@@ -141,4 +141,90 @@ public class EXO2PlayerManager implements IPlayerManager {
public void setSpeedPlaying(float speed, boolean soundTouch) {
}
@Override
public void start() {
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
@Override
public void stop() {
if (mediaPlayer != null) {
mediaPlayer.stop();
}
}
@Override
public void pause() {
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
@Override
public int getVideoWidth() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoWidth();
}
return 0;
}
@Override
public int getVideoHeight() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoHeight();
}
return 0;
}
@Override
public boolean isPlaying() {
if (mediaPlayer != null) {
return mediaPlayer.isPlaying();
}
return false;
}
@Override
public void seekTo(long time) {
if (mediaPlayer != null) {
mediaPlayer.seekTo(time);
}
}
@Override
public long getCurrentPosition() {
if (mediaPlayer != null) {
return mediaPlayer.getCurrentPosition();
}
return 0;
}
@Override
public long getDuration() {
if (mediaPlayer != null) {
return mediaPlayer.getDuration();
}
return 0;
}
@Override
public int getVideoSarNum() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarNum();
}
return 1;
}
@Override
public int getVideoSarDen() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarDen();
}
return 1;
}
}
......@@ -188,6 +188,90 @@ public class IJKPlayerManager implements IPlayerManager {
}
}
@Override
public void start() {
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
@Override
public void stop() {
if (mediaPlayer != null) {
mediaPlayer.stop();
}
}
@Override
public void pause() {
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
@Override
public int getVideoWidth() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoWidth();
}
return 0;
}
@Override
public int getVideoHeight() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoHeight();
}
return 0;
}
@Override
public boolean isPlaying() {
if (mediaPlayer != null) {
return mediaPlayer.isPlaying();
}
return false;
}
@Override
public void seekTo(long time) {
if (mediaPlayer != null) {
mediaPlayer.seekTo(time);
}
}
@Override
public long getCurrentPosition() {
if (mediaPlayer != null) {
return mediaPlayer.getCurrentPosition();
}
return 0;
}
@Override
public long getDuration() {
if (mediaPlayer != null) {
return mediaPlayer.getDuration();
}
return 0;
}
@Override
public int getVideoSarNum() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarNum();
}
return 1;
}
@Override
public int getVideoSarDen() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarDen();
}
return 1;
}
private void initIJKOption(IjkMediaPlayer ijkMediaPlayer, List<VideoOptionModel> optionModelList) {
if (optionModelList != null && optionModelList.size() > 0) {
for (VideoOptionModel videoOptionModel : optionModelList) {
......
......@@ -64,4 +64,26 @@ public interface IPlayerManager {
void setSpeedPlaying(float speed, boolean soundTouch);
void setSpeed(float speed, boolean soundTouch);
void start();
void stop();
void pause();
int getVideoWidth();
int getVideoHeight();
boolean isPlaying();
void seekTo(long time);
long getCurrentPosition();
long getDuration();
int getVideoSarNum();
int getVideoSarDen();
}
......@@ -124,6 +124,92 @@ public class SystemPlayerManager implements IPlayerManager {
}
@Override
public void start() {
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
@Override
public void stop() {
if (mediaPlayer != null) {
mediaPlayer.stop();
}
}
@Override
public void pause() {
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
@Override
public int getVideoWidth() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoWidth();
}
return 0;
}
@Override
public int getVideoHeight() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoHeight();
}
return 0;
}
@Override
public boolean isPlaying() {
if (mediaPlayer != null) {
return mediaPlayer.isPlaying();
}
return false;
}
@Override
public void seekTo(long time) {
if (mediaPlayer != null) {
mediaPlayer.seekTo(time);
}
}
@Override
public long getCurrentPosition() {
if (mediaPlayer != null) {
return mediaPlayer.getCurrentPosition();
}
return 0;
}
@Override
public long getDuration() {
if (mediaPlayer != null) {
return mediaPlayer.getDuration();
}
return 0;
}
@Override
public int getVideoSarNum() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarNum();
}
return 1;
}
@Override
public int getVideoSarDen() {
if (mediaPlayer != null) {
return mediaPlayer.getVideoSarDen();
}
return 1;
}
private void setSpeed(float speed) {
if (release) {
return;
......
......@@ -22,7 +22,6 @@ import com.transitionseverywhere.TransitionManager;
import java.lang.reflect.Constructor;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import static com.shuyu.gsyvideoplayer.utils.CommonUtil.getActionBarHeight;
import static com.shuyu.gsyvideoplayer.utils.CommonUtil.getStatusBarHeight;
......@@ -161,7 +160,7 @@ public abstract class GSYBaseVideoPlayer extends GSYVideoControlView {
@Override
public void onInfo(int what, int extra) {
super.onInfo(what, extra);
if (what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED) {
if (what == getGSYVideoManager().getRotateInfoFlag()) {
checkAutoFullSizeWhenFull();
}
}
......@@ -309,7 +308,7 @@ public abstract class GSYBaseVideoPlayer extends GSYVideoControlView {
postDelayed(new Runnable() {
@Override
public void run() {
Debuger.printfLog("GSYVideoBase resolveFullVideoShow isVerticalFullByVideoSize " + isVertical);
Debuger.printfLog("GSYVideoBase resolveFullVideoShow isVerticalFullByVideoSize " + isVertical);
//autoFull模式下,非横屏视频视频不横屏,并且不自动旋转
if (!isVertical && isLockLand && mOrientationUtils.getIsLand() != 1) {
mOrientationUtils.resolveByClick();
......@@ -473,8 +472,8 @@ public abstract class GSYBaseVideoPlayer extends GSYVideoControlView {
boolean isVertical = false;
int videoHeight = getCurrentVideoHeight();
int videoWidth = getCurrentVideoWidth();
Debuger.printfLog("GSYVideoBase isVerticalVideo videoHeight " + videoHeight + " videoWidth " + videoWidth);
Debuger.printfLog("GSYVideoBase isVerticalVideo mRotate " + mRotate);
Debuger.printfLog("GSYVideoBase isVerticalVideo videoHeight " + videoHeight + " videoWidth " + videoWidth);
Debuger.printfLog("GSYVideoBase isVerticalVideo mRotate " + mRotate);
if (videoHeight > 0 && videoWidth > 0) {
if (mRotate == 90 || mRotate == 270) {
isVertical = videoWidth > videoHeight;
......@@ -923,6 +922,7 @@ public abstract class GSYBaseVideoPlayer extends GSYVideoControlView {
/**
* 是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏,注意,这时候默认旋转无效
*
* @param autoFullWithSize 默认false
*/
public void setAutoFullWithSize(boolean autoFullWithSize) {
......
......@@ -576,10 +576,10 @@ public abstract class GSYVideoControlView extends GSYVideoView implements View.O
mVideoAllCallBack.onClickSeekbar(mOriginUrl, mTitle, this);
}
}
if (getGSYVideoManager().getMediaPlayer() != null && mHadPlay) {
if (getGSYVideoManager() != null && mHadPlay) {
try {
int time = seekBar.getProgress() * getDuration() / 100;
getGSYVideoManager().getMediaPlayer().seekTo(time);
getGSYVideoManager().seekTo(time);
} catch (Exception e) {
Debuger.printfWarning(e.toString());
}
......@@ -714,9 +714,9 @@ public abstract class GSYVideoControlView extends GSYVideoView implements View.O
dismissProgressDialog();
dismissVolumeDialog();
dismissBrightnessDialog();
if (mChangePosition && getGSYVideoManager().getMediaPlayer() != null && (mCurrentState == CURRENT_STATE_PLAYING || mCurrentState == CURRENT_STATE_PAUSE)) {
if (mChangePosition && getGSYVideoManager() != null && (mCurrentState == CURRENT_STATE_PLAYING || mCurrentState == CURRENT_STATE_PAUSE)) {
try {
getGSYVideoManager().getMediaPlayer().seekTo(mSeekTimePosition);
getGSYVideoManager().seekTo(mSeekTimePosition);
} catch (Exception e) {
e.printStackTrace();
}
......@@ -807,7 +807,7 @@ public abstract class GSYVideoControlView extends GSYVideoView implements View.O
startButtonLogic();
} else if (mCurrentState == CURRENT_STATE_PLAYING) {
try {
getGSYVideoManager().getMediaPlayer().pause();
getGSYVideoManager().pause();
} catch (Exception e) {
e.printStackTrace();
}
......@@ -832,7 +832,7 @@ public abstract class GSYVideoControlView extends GSYVideoView implements View.O
}
}
try {
getGSYVideoManager().getMediaPlayer().start();
getGSYVideoManager().start();
} catch (Exception e) {
e.printStackTrace();
}
......
......@@ -29,6 +29,8 @@ public abstract class GSYVideoPlayer extends GSYBaseVideoPlayer {
super(context, attrs, defStyleAttr);
}
/*******************************下面方法为管理器和播放控件交互的方法****************************************/
@Override
public GSYVideoViewBridge getGSYVideoManager() {
GSYVideoManager.instance().initContext(getContext().getApplicationContext());
......
......@@ -28,8 +28,6 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import static com.shuyu.gsyvideoplayer.utils.CommonUtil.getTextSpeed;
/**
......@@ -208,32 +206,32 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
@Override
public int getCurrentVideoWidth() {
if (getGSYVideoManager().getMediaPlayer() != null) {
return getGSYVideoManager().getMediaPlayer().getVideoWidth();
if (getGSYVideoManager() != null) {
return getGSYVideoManager().getVideoWidth();
}
return 0;
}
@Override
public int getCurrentVideoHeight() {
if (getGSYVideoManager().getMediaPlayer() != null) {
return getGSYVideoManager().getMediaPlayer().getVideoHeight();
if (getGSYVideoManager() != null) {
return getGSYVideoManager().getVideoHeight();
}
return 0;
}
@Override
public int getVideoSarNum() {
if (getGSYVideoManager().getMediaPlayer() != null) {
return getGSYVideoManager().getMediaPlayer().getVideoSarNum();
if (getGSYVideoManager() != null) {
return getGSYVideoManager().getVideoSarNum();
}
return 0;
}
@Override
public int getVideoSarDen() {
if (getGSYVideoManager().getMediaPlayer() != null) {
return getGSYVideoManager().getMediaPlayer().getVideoSarDen();
if (getGSYVideoManager() != null) {
return getGSYVideoManager().getVideoSarDen();
}
return 0;
}
......@@ -459,12 +457,12 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
mPauseBeforePrepared = true;
}
try {
if (getGSYVideoManager().getMediaPlayer() != null &&
getGSYVideoManager().getMediaPlayer().isPlaying()) {
if (getGSYVideoManager() != null &&
getGSYVideoManager().isPlaying()) {
setStateAndUi(CURRENT_STATE_PAUSE);
mCurrentPosition = getGSYVideoManager().getMediaPlayer().getCurrentPosition();
if (getGSYVideoManager().getMediaPlayer() != null)
getGSYVideoManager().getMediaPlayer().pause();
mCurrentPosition = getGSYVideoManager().getCurrentPosition();
if (getGSYVideoManager() != null)
getGSYVideoManager().pause();
}
} catch (Exception e) {
e.printStackTrace();
......@@ -489,11 +487,11 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
mPauseBeforePrepared = false;
if (mCurrentState == CURRENT_STATE_PAUSE) {
try {
if (mCurrentPosition > 0 && getGSYVideoManager().getMediaPlayer() != null) {
if (mCurrentPosition > 0 && getGSYVideoManager() != null) {
if (seek) {
getGSYVideoManager().getMediaPlayer().seekTo(mCurrentPosition);
getGSYVideoManager().seekTo(mCurrentPosition);
}
getGSYVideoManager().getMediaPlayer().start();
getGSYVideoManager().start();
setStateAndUi(CURRENT_STATE_PLAYING);
if (mAudioManager != null && !mReleaseWhenLossAudio) {
mAudioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
......@@ -649,7 +647,7 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
mBackUpPlayingBufferState = -1;
}
} else if (what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED) {
} else if (what == getGSYVideoManager().getRotateInfoFlag()) {
mRotate = extra;
Debuger.printfLog("Video Rotate Info " + extra);
if (mTextureView != null)
......@@ -698,7 +696,7 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
int position = 0;
if (mCurrentState == CURRENT_STATE_PLAYING || mCurrentState == CURRENT_STATE_PAUSE) {
try {
position = (int) getGSYVideoManager().getMediaPlayer().getCurrentPosition();
position = (int) getGSYVideoManager().getCurrentPosition();
} catch (Exception e) {
e.printStackTrace();
return position;
......@@ -716,7 +714,7 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
public int getDuration() {
int duration = 0;
try {
duration = (int) getGSYVideoManager().getMediaPlayer().getDuration();
duration = (int) getGSYVideoManager().getDuration();
} catch (Exception e) {
e.printStackTrace();
return duration;
......@@ -745,14 +743,14 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
}
try {
if (getGSYVideoManager().getMediaPlayer() != null) {
getGSYVideoManager().getMediaPlayer().start();
if (getGSYVideoManager() != null) {
getGSYVideoManager().start();
}
setStateAndUi(CURRENT_STATE_PLAYING);
if (getGSYVideoManager().getMediaPlayer() != null && mSeekOnStart > 0) {
getGSYVideoManager().getMediaPlayer().seekTo(mSeekOnStart);
if (getGSYVideoManager() != null && mSeekOnStart > 0) {
getGSYVideoManager().seekTo(mSeekOnStart);
mSeekOnStart = 0;
}
} catch (Exception e) {
......@@ -1002,7 +1000,7 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
public void setSpeed(float speed, boolean soundTouch) {
this.mSpeed = speed;
this.mSoundTouch = soundTouch;
if (getGSYVideoManager().getMediaPlayer() != null) {
if (getGSYVideoManager() != null) {
getGSYVideoManager().setSpeed(speed, soundTouch);
}
}
......@@ -1038,8 +1036,8 @@ public abstract class GSYVideoView extends GSYTextureRenderView implements GSYMe
*/
public void seekTo(long position) {
try {
if (getGSYVideoManager().getMediaPlayer() != null && position > 0) {
getGSYVideoManager().getMediaPlayer().seekTo(position);
if (getGSYVideoManager()!= null && position > 0) {
getGSYVideoManager().seekTo(position);
}
} catch (Exception e) {
e.printStackTrace();
......
......@@ -4,12 +4,11 @@ import android.content.Context;
import android.view.Surface;
import com.shuyu.gsyvideoplayer.listener.GSYMediaPlayerListener;
import com.shuyu.gsyvideoplayer.player.IPlayerManager;
import java.io.File;
import java.util.Map;
import tv.danmaku.ijk.media.player.IMediaPlayer;
/**
* Manager 与 View之间的接口
* Created by guoshuyu on 2018/1/25.
......@@ -48,7 +47,7 @@ public interface GSYVideoViewBridge {
/**
* 获取当前播放内核
*/
IMediaPlayer getMediaPlayer();
IPlayerManager getPlayer();
/**
* 针对某些内核,缓冲百分比
......@@ -119,4 +118,31 @@ public interface GSYVideoViewBridge {
* @param soundTouch
*/
void setSpeedPlaying(float speed, boolean soundTouch);
/**
* 获取Rotate选择的flag,目前只有ijk用到
*/
int getRotateInfoFlag();
void start();
void stop();
void pause();
int getVideoWidth();
int getVideoHeight();
boolean isPlaying();
void seekTo(long time);
long getCurrentPosition();
long getDuration();
int getVideoSarNum();
int getVideoSarDen();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册