[*] 日常优化
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
package com.acgist.taoyao.boot.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 集合工具
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public final class ListUtils {
|
||||
|
||||
private ListUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> 集合类型
|
||||
* @param list 集合
|
||||
* @param function 执行函数
|
||||
*
|
||||
* @return 集合首个元素执行函数返回结果
|
||||
*/
|
||||
public static final <T> T getOnlyOne(List<T> list, Function<T, T> function) {
|
||||
if(list == null || list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final int size = list.size();
|
||||
if(size > 1) {
|
||||
Log.w(ListUtils.class.getSimpleName(), "集合不止一条数据:" + size);
|
||||
}
|
||||
return function.apply(list.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* 混音处理器
|
||||
*
|
||||
* JavaAudioDeviceModule : 音频
|
||||
* JavaAudioDeviceModule : 音频模块
|
||||
* WebRtcAudioTrack#AudioTrackThread :远程音频
|
||||
* WebRtcAudioRecord#AudioRecordThread:本地音频
|
||||
*
|
||||
@@ -33,7 +33,7 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
|
||||
/**
|
||||
* 音频数据来源
|
||||
* 其实不用切换可以两个同时录制,但是有点浪费资源。
|
||||
* 其实可以不用切换可以两个同时录制,但是有点浪费资源。
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
@@ -44,18 +44,56 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
WEBRTC;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否关闭
|
||||
*/
|
||||
private boolean close;
|
||||
/**
|
||||
* 音频数据来源
|
||||
*/
|
||||
private Source source;
|
||||
/**
|
||||
* 采样率
|
||||
*/
|
||||
private final int sampleRate;
|
||||
/**
|
||||
* 音频格式
|
||||
*/
|
||||
private final int audioFormat;
|
||||
/**
|
||||
* 音频来源
|
||||
*/
|
||||
private final int audioSource;
|
||||
/**
|
||||
* 通道数量
|
||||
*/
|
||||
private final int channelCount;
|
||||
/**
|
||||
* 通道配置
|
||||
*/
|
||||
private final int channelConfig;
|
||||
/**
|
||||
* 录音器
|
||||
*/
|
||||
private final AudioRecord audioRecord;
|
||||
/**
|
||||
* 录像机
|
||||
*/
|
||||
private final RecordClient recordClient;
|
||||
/**
|
||||
* 本地音频队列
|
||||
*/
|
||||
private final BlockingQueue<JavaAudioDeviceModule.AudioSamples> local;
|
||||
/**
|
||||
* 远程音频队列
|
||||
*/
|
||||
private final BlockingQueue<JavaAudioDeviceModule.AudioSamples> remote;
|
||||
|
||||
/**
|
||||
* @param sampleRate 采样率
|
||||
* @param channelCount 通道数量
|
||||
* @param recordClient 录像机
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
public MixerProcesser(int sampleRate, int channelCount, RecordClient recordClient) {
|
||||
this.setDaemon(true);
|
||||
@@ -79,8 +117,8 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
.setBufferSizeInBytes(AudioRecord.getMinBufferSize(this.sampleRate, this.channelConfig, this.audioFormat))
|
||||
.build();
|
||||
this.recordClient = recordClient;
|
||||
this.local = new LinkedBlockingQueue<>(1024);
|
||||
this.remote = new LinkedBlockingQueue<>(1024);
|
||||
this.local = new LinkedBlockingQueue<>(1024);
|
||||
this.remote = new LinkedBlockingQueue<>(1024);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,16 +139,16 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long pts = System.nanoTime();
|
||||
long pts = System.nanoTime();
|
||||
int recordSize = 0;
|
||||
int mixDataLength = 0;
|
||||
byte[] mixData = null;
|
||||
byte[] localData = null;
|
||||
byte[] remoteData = null;
|
||||
byte[] recordData = null;
|
||||
int mixDataLength = 0;
|
||||
JavaAudioDeviceModule.AudioSamples local = null;
|
||||
JavaAudioDeviceModule.AudioSamples remote = null;
|
||||
int recordSize = 0;
|
||||
// 采集数据大小:采样频率 / (一秒 / 回调频率) * 通道数量 * 采样数据大小
|
||||
// 采集数据大小:采样频率 / (一千毫秒 / 回调频率毫秒) * 通道数量 * 采样数据大小
|
||||
final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(this.sampleRate / (1000 / 10) * this.channelCount * 2);
|
||||
while(!this.close) {
|
||||
try {
|
||||
@@ -126,6 +164,7 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
} else if(this.source == Source.WEBRTC) {
|
||||
// 平均10毫秒
|
||||
local = this.local.poll(64, TimeUnit.MILLISECONDS);
|
||||
// 远程数据不要等待
|
||||
remote = this.remote.poll();
|
||||
if(local != null && remote != null) {
|
||||
// Log.d(MixerProcesser.class.getSimpleName(), String.format("""
|
||||
@@ -140,8 +179,7 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
// ));
|
||||
localData = local.getData();
|
||||
remoteData = remote.getData();
|
||||
if(mixDataLength != localData.length) {
|
||||
// if(mixDataLength != localData.length && mixDataLength != remoteData.length) {
|
||||
if(mixDataLength != localData.length && mixDataLength != remoteData.length) {
|
||||
mixDataLength = localData.length;
|
||||
mixData = new byte[mixDataLength];
|
||||
}
|
||||
@@ -164,7 +202,6 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
this.recordClient.onPcm(pts, remoteData);
|
||||
} else {
|
||||
Thread.yield();
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
Thread.yield();
|
||||
@@ -203,6 +240,9 @@ public class MixerProcesser extends Thread implements JavaAudioDeviceModule.Samp
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭混音
|
||||
*/
|
||||
public void close() {
|
||||
synchronized (this) {
|
||||
this.close = true;
|
||||
|
||||
@@ -28,9 +28,15 @@ public abstract class Client extends CloseableClient {
|
||||
*/
|
||||
protected SurfaceViewRenderer surfaceViewRenderer;
|
||||
|
||||
/**
|
||||
* @param name 终端名称
|
||||
* @param clientId 终端ID
|
||||
* @param taoyao 信令
|
||||
* @param mainHandler MainHandler
|
||||
*/
|
||||
public Client(String name, String clientId, ITaoyao taoyao, Handler mainHandler) {
|
||||
super(taoyao, mainHandler);
|
||||
this.name = name;
|
||||
this.name = name;
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
@@ -40,9 +46,15 @@ public abstract class Client extends CloseableClient {
|
||||
public void playAudio() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停音频
|
||||
*/
|
||||
public void pauseAudio() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复音频
|
||||
*/
|
||||
public void resumeAudio() {
|
||||
}
|
||||
|
||||
@@ -52,23 +64,32 @@ public abstract class Client extends CloseableClient {
|
||||
public void playVideo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停视频
|
||||
*/
|
||||
public void pauseVideo() {
|
||||
if(this.surfaceViewRenderer != null) {
|
||||
this.surfaceViewRenderer.pauseVideo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复视频
|
||||
*/
|
||||
public void resumeVideo() {
|
||||
if(this.surfaceViewRenderer != null) {
|
||||
// TODO:验证是否正确
|
||||
this.surfaceViewRenderer.disableFpsReduction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停音视频
|
||||
*/
|
||||
public void pause() {
|
||||
this.pauseAudio();
|
||||
this.pauseVideo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复音视频
|
||||
*/
|
||||
public void resume() {
|
||||
this.resumeAudio();
|
||||
this.resumeVideo();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,7 +16,6 @@ public abstract class CloseableClient implements Closeable {
|
||||
|
||||
/**
|
||||
* 是否加载
|
||||
* 防止重复加载
|
||||
*/
|
||||
protected volatile boolean init;
|
||||
/**
|
||||
@@ -28,7 +27,7 @@ public abstract class CloseableClient implements Closeable {
|
||||
*/
|
||||
protected final ITaoyao taoyao;
|
||||
/**
|
||||
* Handler
|
||||
* MainHandler
|
||||
*/
|
||||
protected final Handler mainHandler;
|
||||
/**
|
||||
@@ -36,11 +35,15 @@ public abstract class CloseableClient implements Closeable {
|
||||
*/
|
||||
protected final MediaManager mediaManager;
|
||||
|
||||
/**
|
||||
* @param taoyao 信令
|
||||
* @param mainHandler MainHandler
|
||||
*/
|
||||
public CloseableClient(ITaoyao taoyao, Handler mainHandler) {
|
||||
this.init = false;
|
||||
this.close = false;
|
||||
this.taoyao = taoyao;
|
||||
this.mainHandler = mainHandler;
|
||||
this.init = false;
|
||||
this.close = false;
|
||||
this.taoyao = taoyao;
|
||||
this.mainHandler = mainHandler;
|
||||
this.mediaManager = MediaManager.getInstance();
|
||||
}
|
||||
|
||||
@@ -56,4 +59,5 @@ public abstract class CloseableClient implements Closeable {
|
||||
public void close() {
|
||||
this.close = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.acgist.taoyao.media.client;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.acgist.taoyao.boot.utils.ListUtils;
|
||||
import com.acgist.taoyao.media.config.Config;
|
||||
import com.acgist.taoyao.media.signal.ITaoyao;
|
||||
|
||||
@@ -29,18 +28,36 @@ public class LocalClient extends RoomClient {
|
||||
* 生产者ID = 媒体流Track指针
|
||||
*/
|
||||
protected final Map<String, Long> tracks;
|
||||
/**
|
||||
* 音频媒体生产者指针
|
||||
*/
|
||||
protected long audioProducerPointer;
|
||||
/**
|
||||
* 视频媒体生产者指针
|
||||
*/
|
||||
protected long videoProducerPointer;
|
||||
|
||||
/**
|
||||
* @param name 终端名称
|
||||
* @param clientId 终端ID
|
||||
* @param taoyao 信令
|
||||
* @param mainHandler MainHandler
|
||||
*/
|
||||
public LocalClient(String name, String clientId, ITaoyao taoyao, Handler mainHandler) {
|
||||
super(name, clientId, taoyao, mainHandler);
|
||||
this.tracks = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 媒体流
|
||||
*/
|
||||
public MediaStream getMediaStream() {
|
||||
return this.mediaStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mediaStream 媒体流
|
||||
*/
|
||||
public void setMediaStream(MediaStream mediaStream) {
|
||||
this.mediaStream = mediaStream;
|
||||
}
|
||||
@@ -51,10 +68,31 @@ public class LocalClient extends RoomClient {
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
ListUtils.getOnlyOne(this.mediaStream.audioTracks, audioTrack -> {
|
||||
this.mediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(Config.DEFAULT_VOLUME);
|
||||
audioTrack.setEnabled(true);
|
||||
return audioTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseAudio() {
|
||||
super.pauseAudio();
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
this.mediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeAudio() {
|
||||
super.resumeAudio();
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
this.mediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -64,12 +102,33 @@ public class LocalClient extends RoomClient {
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
ListUtils.getOnlyOne(this.mediaStream.videoTracks, videoTrack -> {
|
||||
this.mediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
if(this.surfaceViewRenderer == null) {
|
||||
this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_LOCAL_VIDEO, videoTrack);
|
||||
}
|
||||
return videoTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseVideo() {
|
||||
super.pauseVideo();
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
this.mediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeVideo() {
|
||||
super.resumeVideo();
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
this.mediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,12 +155,17 @@ public class LocalClient extends RoomClient {
|
||||
* @param producerId 生产者ID
|
||||
*/
|
||||
public void close(String producerId) {
|
||||
Log.i(RemoteClient.class.getSimpleName(), "关闭本地终端生产者者:" + this.clientId + " - " + producerId);
|
||||
final Long pointer = this.tracks.get(producerId);
|
||||
if(pointer == null || this.mediaStream == null) {
|
||||
if(this.mediaStream == null) {
|
||||
return;
|
||||
}
|
||||
Log.i(RemoteClient.class.getSimpleName(), "关闭本地终端生产者:" + this.clientId + " - " + producerId);
|
||||
synchronized (this.mediaStream) {
|
||||
final Long pointer = this.tracks.get(producerId);
|
||||
// TODO:测试remove方法
|
||||
// final Long pointer = this.tracks.remove(producerId);
|
||||
if(pointer == null) {
|
||||
return;
|
||||
}
|
||||
if(pointer.equals(this.audioProducerPointer)) {
|
||||
this.mediaStream.audioTracks.forEach(MediaStreamTrack::dispose);
|
||||
this.mediaStream.audioTracks.clear();
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.acgist.taoyao.media.client;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.acgist.taoyao.boot.utils.ListUtils;
|
||||
import com.acgist.taoyao.media.config.Config;
|
||||
import com.acgist.taoyao.media.signal.ITaoyao;
|
||||
|
||||
@@ -13,10 +12,10 @@ import org.webrtc.VideoTrack;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 房间远程终端
|
||||
* 注意:这里媒体MediaStreamTrack使用Mediasoup方法释放不要直接调用MediaStreamTrack.dispose()释放
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
@@ -39,35 +38,67 @@ public class RemoteClient extends RoomClient {
|
||||
@Override
|
||||
public void playAudio() {
|
||||
super.playAudio();
|
||||
ListUtils.getOnlyOne(
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.AUDIO_TRACK_KIND.equals(v.kind()))
|
||||
.map(v -> (AudioTrack) v)
|
||||
.collect(Collectors.toList()),
|
||||
audioTrack -> {
|
||||
audioTrack.setVolume(Config.DEFAULT_VOLUME);
|
||||
audioTrack.setEnabled(true);
|
||||
return audioTrack;
|
||||
}
|
||||
);
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.AUDIO_TRACK_KIND.equals(v.kind()))
|
||||
.map(v -> (AudioTrack) v)
|
||||
.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(Config.DEFAULT_VOLUME);
|
||||
audioTrack.setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseAudio() {
|
||||
super.pauseAudio();
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.AUDIO_TRACK_KIND.equals(v.kind()))
|
||||
.forEach(audioTrack -> {
|
||||
audioTrack.setEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeAudio() {
|
||||
super.resumeAudio();
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.AUDIO_TRACK_KIND.equals(v.kind()))
|
||||
.forEach(audioTrack -> {
|
||||
audioTrack.setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playVideo() {
|
||||
super.playVideo();
|
||||
ListUtils.getOnlyOne(
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.VIDEO_TRACK_KIND.equals(v.kind()))
|
||||
.map(v -> (VideoTrack) v)
|
||||
.collect(Collectors.toList()),
|
||||
videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
if(this.surfaceViewRenderer == null) {
|
||||
this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_REMOTE_VIDEO, videoTrack);
|
||||
}
|
||||
return videoTrack;
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.VIDEO_TRACK_KIND.equals(v.kind()))
|
||||
.map(v -> (VideoTrack) v)
|
||||
.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
if(this.surfaceViewRenderer == null) {
|
||||
this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_REMOTE_VIDEO, videoTrack);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseVideo() {
|
||||
super.pauseVideo();
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.VIDEO_TRACK_KIND.equals(v.kind()))
|
||||
.forEach(audioTrack -> {
|
||||
audioTrack.setEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeVideo() {
|
||||
super.resumeVideo();
|
||||
this.tracks.values().stream()
|
||||
.filter(v -> MediaStreamTrack.VIDEO_TRACK_KIND.equals(v.kind()))
|
||||
.forEach(audioTrack -> {
|
||||
audioTrack.setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +110,7 @@ public class RemoteClient extends RoomClient {
|
||||
super.close();
|
||||
Log.i(RemoteClient.class.getSimpleName(), "关闭远程终端:" + this.clientId);
|
||||
synchronized (this.tracks) {
|
||||
// 注意:使用nativeMediaConsumerClose释放
|
||||
// 注意:使用nativeMediaConsumerClose释放资源
|
||||
this.tracks.clear();
|
||||
}
|
||||
}
|
||||
@@ -93,7 +124,7 @@ public class RemoteClient extends RoomClient {
|
||||
public void close(String consumerId) {
|
||||
Log.i(RemoteClient.class.getSimpleName(), "关闭远程终端消费者:" + this.clientId + " - " + consumerId);
|
||||
synchronized (this.tracks) {
|
||||
// 注意:使用nativeMediaConsumerClose释放
|
||||
// 注意:使用nativeMediaConsumerClose释放资源
|
||||
this.tracks.remove(consumerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.acgist.taoyao.boot.model.Message;
|
||||
import com.acgist.taoyao.boot.utils.ListUtils;
|
||||
import com.acgist.taoyao.boot.utils.MapUtils;
|
||||
import com.acgist.taoyao.media.config.Config;
|
||||
import com.acgist.taoyao.media.config.MediaProperties;
|
||||
@@ -231,30 +230,33 @@ public class SessionClient extends Client {
|
||||
if(this.remoteMediaStream == null) {
|
||||
return;
|
||||
}
|
||||
ListUtils.getOnlyOne(this.remoteMediaStream.audioTracks, audioTrack -> {
|
||||
this.remoteMediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(Config.DEFAULT_VOLUME);
|
||||
audioTrack.setEnabled(true);
|
||||
return audioTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseAudio() {
|
||||
super.pauseAudio();
|
||||
ListUtils.getOnlyOne(this.remoteMediaStream.audioTracks, audioTrack -> {
|
||||
if(this.remoteMediaStream == null) {
|
||||
return;
|
||||
}
|
||||
this.remoteMediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(0);
|
||||
audioTrack.setEnabled(false);
|
||||
return audioTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeAudio() {
|
||||
super.resumeAudio();
|
||||
ListUtils.getOnlyOne(this.remoteMediaStream.audioTracks, audioTrack -> {
|
||||
if(this.remoteMediaStream == null) {
|
||||
return;
|
||||
}
|
||||
this.remoteMediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(Config.DEFAULT_VOLUME);
|
||||
audioTrack.setEnabled(true);
|
||||
return audioTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -264,74 +266,67 @@ public class SessionClient extends Client {
|
||||
if(this.remoteMediaStream == null) {
|
||||
return;
|
||||
}
|
||||
ListUtils.getOnlyOne(this.remoteMediaStream.videoTracks, videoTrack -> {
|
||||
this.remoteMediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
if(this.surfaceViewRenderer == null) {
|
||||
this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_REMOTE_VIDEO, videoTrack);
|
||||
}
|
||||
return videoTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseVideo() {
|
||||
super.pauseVideo();
|
||||
ListUtils.getOnlyOne(this.remoteMediaStream.videoTracks, videoTrack -> {
|
||||
if(this.remoteMediaStream == null) {
|
||||
return;
|
||||
}
|
||||
if(this.surfaceViewRenderer != null) {
|
||||
// TODO:测试
|
||||
this.surfaceViewRenderer.pauseVideo();
|
||||
}
|
||||
this.remoteMediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(false);
|
||||
return videoTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeVideo() {
|
||||
super.resumeVideo();
|
||||
ListUtils.getOnlyOne(this.remoteMediaStream.videoTracks, videoTrack -> {
|
||||
if(this.remoteMediaStream == null) {
|
||||
return;
|
||||
}
|
||||
if(this.surfaceViewRenderer != null) {
|
||||
// TODO:测试
|
||||
this.surfaceViewRenderer.disableFpsReduction();
|
||||
}
|
||||
this.remoteMediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
return videoTrack;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
super.pause();
|
||||
this.pauseAudio();
|
||||
this.pauseVideo();
|
||||
}
|
||||
|
||||
public void pause(String type) {
|
||||
if(MediaStreamTrack.AUDIO_TRACK_KIND.equals(type)) {
|
||||
ListUtils.getOnlyOne(this.mediaStream.audioTracks, audioTrack -> {
|
||||
this.mediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(0);
|
||||
audioTrack.setEnabled(false);
|
||||
return audioTrack;
|
||||
});
|
||||
} else if(MediaStreamTrack.VIDEO_TRACK_KIND.equals(type)) {
|
||||
ListUtils.getOnlyOne(this.mediaStream.videoTracks, videoTrack -> {
|
||||
this.mediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(false);
|
||||
return videoTrack;
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
super.resume();
|
||||
this.resumeAudio();
|
||||
this.resumeVideo();
|
||||
}
|
||||
|
||||
public void resume(String type) {
|
||||
if(MediaStreamTrack.AUDIO_TRACK_KIND.equals(type)) {
|
||||
ListUtils.getOnlyOne(this.mediaStream.audioTracks, audioTrack -> {
|
||||
this.mediaStream.audioTracks.forEach(audioTrack -> {
|
||||
audioTrack.setVolume(Config.DEFAULT_VOLUME);
|
||||
audioTrack.setEnabled(true);
|
||||
return audioTrack;
|
||||
});
|
||||
} else if(MediaStreamTrack.VIDEO_TRACK_KIND.equals(type)) {
|
||||
ListUtils.getOnlyOne(this.mediaStream.videoTracks, videoTrack -> {
|
||||
this.mediaStream.videoTracks.forEach(videoTrack -> {
|
||||
videoTrack.setEnabled(true);
|
||||
return videoTrack;
|
||||
});
|
||||
} else {
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<div class="client">
|
||||
<audio ref="audio"></audio>
|
||||
<video ref="video"></video>
|
||||
<p class="title">{{ client?.name || "" }}</p>
|
||||
<p class="title">{{ client.name || "" }}</p>
|
||||
<div class="buttons">
|
||||
<el-button @click="taoyao.mediaProducerResume(audioProducer.id)" v-show="audioProducer && audioProducer.paused" type="danger" title="打开麦克风" :icon="Mute" circle />
|
||||
<el-button @click="taoyao.mediaProducerPause(audioProducer.id)" v-show="audioProducer && !audioProducer.paused" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client?.volume}" />
|
||||
<el-button @click="taoyao.mediaProducerPause(audioProducer.id)" v-show="audioProducer && !audioProducer.paused" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client.volume}" />
|
||||
<el-button @click="taoyao.mediaProducerResume(videoProducer.id)" v-show="videoProducer && videoProducer.paused" type="danger" title="打开摄像头" :icon="VideoPlay" circle />
|
||||
<el-button @click="taoyao.mediaProducerPause(videoProducer.id)" v-show="videoProducer && !videoProducer.paused" type="primary" title="关闭摄像头" :icon="VideoPause" circle />
|
||||
<el-button @click="exchangeVideoSource" :icon="Refresh" circle title="交换媒体" />
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
<div class="client">
|
||||
<audio ref="audio"></audio>
|
||||
<video ref="video"></video>
|
||||
<p class="title">{{ client?.name || "" }}</p>
|
||||
<p class="title">{{ client.name || "" }}</p>
|
||||
<div class="buttons">
|
||||
<el-button @click="taoyao.mediaConsumerResume(audioConsumer.id)" v-show="audioConsumer && audioConsumer.paused" type="danger" title="打开麦克风" :icon="Mute" circle />
|
||||
<el-button @click="taoyao.mediaConsumerPause(audioConsumer.id)" v-show="audioConsumer && !audioConsumer.paused" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client?.volume}" />
|
||||
<el-button @click="taoyao.mediaConsumerPause(audioConsumer.id)" v-show="audioConsumer && !audioConsumer.paused" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client.volume}" />
|
||||
<el-button @click="taoyao.mediaConsumerResume(videoConsumer.id)" v-show="videoConsumer && videoConsumer.paused" type="danger" title="打开摄像头" :icon="VideoPlay" circle />
|
||||
<el-button @click="taoyao.mediaConsumerPause(videoConsumer.id)" v-show="videoConsumer && !videoConsumer.paused" type="primary" title="关闭摄像头" :icon="VideoPause" circle />
|
||||
<el-button @click="taoyao.controlPhotograph(client.clientId)" :icon="Camera" circle title="拍照" />
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
<div class="client">
|
||||
<audio ref="audio"></audio>
|
||||
<video ref="video"></video>
|
||||
<p class="title">{{ client?.name || "" }}</p>
|
||||
<p class="title">{{ client.name || "" }}</p>
|
||||
<div class="buttons">
|
||||
<el-button @click="taoyao.sessionResume(client.id, 'audio')" v-show="audioStream && !client.remoteAudioEnabled" type="danger" title="打开麦克风" :icon="Mute" circle />
|
||||
<el-button @click="taoyao.sessionPause(client.id, 'audio')" v-show="audioStream && client.remoteAudioEnabled" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client?.volume}" />
|
||||
<el-button @click="taoyao.sessionResume(client.id, 'video')" v-show="videoStream && !client.remoteVideoEnabled" type="danger" title="打开摄像头" :icon="VideoPlay" circle />
|
||||
<el-button @click="taoyao.sessionPause(client.id, 'video')" v-show="videoStream && client.remoteVideoEnabled" type="primary" title="关闭摄像头" :icon="VideoPause" circle />
|
||||
<el-button @click="client.pause('audio')" v-show="client.localAudioEnabled" type="primary" title="关闭本地麦克风" :icon="Mic" circle />
|
||||
<el-button @click="client.resume('audio')" v-show="!client.localAudioEnabled" type="danger" title="打开本地麦克风" :icon="Mic" circle />
|
||||
<el-button @click="client.pause('video')" v-show="client.localVideoEnabled" type="primary" title="关闭本地摄像头" :icon="Film" circle />
|
||||
<el-button @click="client.resume('video')" v-show="!client.localVideoEnabled" type="danger" title="打开本地摄像头" :icon="Film" circle />
|
||||
<el-button @click="taoyao.sessionResume(client.id, 'audio')" v-show="audioStream && !client.remoteAudioEnabled" type="danger" title="打开远程麦克风" :icon="Mute" circle />
|
||||
<el-button @click="taoyao.sessionPause(client.id, 'audio')" v-show="audioStream && client.remoteAudioEnabled" type="primary" title="关闭远程麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client.volume}" />
|
||||
<el-button @click="taoyao.sessionResume(client.id, 'video')" v-show="videoStream && !client.remoteVideoEnabled" type="danger" title="打开远程摄像头" :icon="VideoPlay" circle />
|
||||
<el-button @click="taoyao.sessionPause(client.id, 'video')" v-show="videoStream && client.remoteVideoEnabled" type="primary" title="关闭远程摄像头" :icon="VideoPause" circle />
|
||||
<el-button @click="taoyao.controlPhotograph(client.clientId)" :icon="Camera" circle title="拍照" />
|
||||
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" :icon="VideoCamera" circle title="录像" :type="record ? 'danger' : ''" />
|
||||
<el-popover placement="top" :width="240" trigger="hover">
|
||||
@@ -27,6 +31,8 @@
|
||||
|
||||
<script>
|
||||
import {
|
||||
Mic,
|
||||
Film,
|
||||
Mute,
|
||||
Camera,
|
||||
Refresh,
|
||||
@@ -41,6 +47,8 @@ export default {
|
||||
name: "SessionClient",
|
||||
setup() {
|
||||
return {
|
||||
Mic,
|
||||
Film,
|
||||
Mute,
|
||||
Camera,
|
||||
Refresh,
|
||||
|
||||
Reference in New Issue
Block a user