Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
/_ReSharper.Caches/
/.vs/SCPSLAudioApi/FileContentIndex
93 changes: 61 additions & 32 deletions SCPSLAudioApi/AudioCore/AudioPlayerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using MEC;
using Mirror;
using NVorbis;
using PluginAPI.Core;
using UnityEngine;
Expand All @@ -19,7 +20,7 @@ public class AudioPlayerBase : MonoBehaviour
public static Dictionary<ReferenceHub, AudioPlayerBase> AudioPlayers = new Dictionary<ReferenceHub, AudioPlayerBase>();

#region Internal

public const int HeadSamples = 1920;
public OpusEncoder Encoder { get; } = new OpusEncoder(VoiceChat.Codec.Enums.OpusApplicationType.Voip);
public PlaybackBuffer PlaybackBuffer { get; } = new PlaybackBuffer();
Expand All @@ -34,61 +35,61 @@ public class AudioPlayerBase : MonoBehaviour
public VorbisReader VorbisReader { get; set; }
public float[] SendBuffer { get; set; }
public float[] ReadBuffer { get; set; }

#endregion

#region AudioPlayer Settings

/// <summary>
/// The ReferenceHub instance that this player sends as.
/// </summary>
public ReferenceHub Owner { get; set; }

/// <summary>
/// Volume that the player will play at.
/// </summary>
public float Volume { get; set; } = 100f;

/// <summary>
/// List of Paths/Urls that the player will play from (Urls only work if <see cref="AllowUrl"/> is true)
/// </summary>
public List<string> AudioToPlay = new List<string>();

/// <summary>
/// Path/Url of the currently playing audio file.
/// </summary>
public string CurrentPlay;

/// <summary>
/// Stream containing the Audio data
/// </summary>
public MemoryStream CurrentPlayStream;

/// <summary>
/// Boolean indicating whether or not the Queue will loop (Audio will be added to the end of the queue after it gets removed on play)
/// </summary>
public bool Loop = false;

/// <summary>
/// If the playlist should be shuffled when an audio track start.
/// </summary>
public bool Shuffle = false;

/// <summary>
/// Whether the Player should continue playing by itself after the current Track ends.
/// </summary>
public bool Continue = true;

/// <summary>
/// Whether the Player should be sending audio to the broadcaster.
/// </summary>
public bool ShouldPlay = true;

/// <summary>
/// If URLs are allowed to be played
/// </summary>
public bool AllowUrl = false;

/// <summary>
/// If Debug logs shouldbe shown (Note: can be very spammy)
/// </summary>
Expand All @@ -107,7 +108,7 @@ public class AudioPlayerBase : MonoBehaviour
#endregion

#region Events

/// <summary>
/// Fired when a track is getting selected.
/// </summary>
Expand All @@ -116,7 +117,7 @@ public class AudioPlayerBase : MonoBehaviour
/// <param name="queuePos">Position in the Queue of the track that is going to be selected</param>
public delegate void TrackSelecting(AudioPlayerBase playerBase, bool directPlay, ref int queuePos);
public static event TrackSelecting OnTrackSelecting;

/// <summary>
/// Fired when a track has been selected
/// </summary>
Expand All @@ -126,8 +127,8 @@ public class AudioPlayerBase : MonoBehaviour
/// <param name="track">The track the AudioPlayer will play</param>
public delegate void TrackSelected(AudioPlayerBase playerBase, bool directPlay, int queuePos, ref string track);
public static event TrackSelected OnTrackSelected;


/// <summary>
/// Fired when a track is loaded and will begin playing.
/// </summary>
Expand All @@ -137,7 +138,7 @@ public class AudioPlayerBase : MonoBehaviour
/// <param name="track">The track the AudioPlayer will play</param>
public delegate void TrackLoaded(AudioPlayerBase playerBase, bool directPlay, int queuePos, string track);
public static event TrackLoaded OnTrackLoaded;

/// <summary>
/// Fired when a track finishes.
/// </summary>
Expand All @@ -150,6 +151,21 @@ public class AudioPlayerBase : MonoBehaviour

#endregion

#region Other Settings
/// <summary>
/// If Info logs shouldbe shown (Note: can be very spammy)
/// </summary>
public bool LogInfo = false;
/// <summary>
/// The audio play is finish.
/// </summary>
public bool IsFinish = false;
/// <summary>
/// when audio play is finished,clear self and fake player.
/// </summary>
public bool AutoClear = true;
#endregion

/// <summary>
/// Add or retrieve the AudioPlayerBase instance based on a ReferenceHub instance.
/// </summary>
Expand Down Expand Up @@ -179,7 +195,7 @@ public virtual void Play(int queuePos)
Timing.KillCoroutines(PlaybackCoroutine);
PlaybackCoroutine = Timing.RunCoroutine(Playback(queuePos), Segment.FixedUpdate);
}

/// <summary>
/// Stops playing the current Track, or stops the player entirely if Clear is true.
/// </summary>
Expand All @@ -190,7 +206,7 @@ public virtual void Stoptrack(bool Clear)
AudioToPlay.Clear();
stopTrack = true;
}

/// <summary>
/// Add an audio file to the queue
/// </summary>
Expand All @@ -208,11 +224,14 @@ public virtual void OnDestroy()
{
if (PlaybackCoroutine.IsValid)
Timing.KillCoroutines(PlaybackCoroutine);
ReferenceHub.AllHubs.Remove(Owner);
NetworkServer.Destroy(Owner.gameObject);
AudioPlayers.Remove(Owner);
}

public virtual IEnumerator<float> Playback(int position)
{
IsFinish = false;
stopTrack = false;
int index = position;
OnTrackSelecting?.Invoke(this, index == -1, ref index);
Expand All @@ -228,13 +247,14 @@ public virtual IEnumerator<float> Playback(int position)
}
}
OnTrackSelected?.Invoke(this, index == -1, index, ref CurrentPlay);
Log.Info($"Loading Audio");
if (LogInfo)
Log.Info($"Loading Audio");
if (AllowUrl && Uri.TryCreate(CurrentPlay, UriKind.Absolute, out Uri result))
{
UnityWebRequest www = new UnityWebRequest(CurrentPlay, "GET");
DownloadHandlerBuffer dH = new DownloadHandlerBuffer();
www.downloadHandler = dH;

yield return Timing.WaitUntilDone(www.SendWebRequest());

if (www.responseCode != 200)
Expand Down Expand Up @@ -274,9 +294,9 @@ public virtual IEnumerator<float> Playback(int position)
yield break;
}
}

CurrentPlayStream.Seek(0, SeekOrigin.Begin);

VorbisReader = new NVorbis.VorbisReader(CurrentPlayStream);

if (VorbisReader.Channels >= 2)
Expand All @@ -289,7 +309,7 @@ public virtual IEnumerator<float> Playback(int position)
CurrentPlayStream.Dispose();
yield break;
}

if (VorbisReader.SampleRate != 48000)
{
Log.Error($"Audio file {CurrentPlay} is not valid. Audio files must have a SamepleRate of 48000");
Expand All @@ -301,7 +321,8 @@ public virtual IEnumerator<float> Playback(int position)
yield break;
}
OnTrackLoaded?.Invoke(this, index == -1, index, CurrentPlay);
Log.Info($"Playing {CurrentPlay} with samplerate of {VorbisReader.SampleRate}");
if (LogInfo)
Log.Info($"Playing {CurrentPlay} with samplerate of {VorbisReader.SampleRate}");
samplesPerSecond = VoiceChatSettings.SampleRate * VoiceChatSettings.Channels;
//_samplesPerSecond = VorbisReader.Channels * VorbisReader.SampleRate / 5;
SendBuffer = new float[samplesPerSecond / 5 + HeadSamples];
Expand All @@ -328,11 +349,13 @@ public virtual IEnumerator<float> Playback(int position)
StreamBuffer.Enqueue(ReadBuffer[i]);
}
}
Log.Info($"Track Complete.");
if (LogInfo)
Log.Info($"Track Complete.");

int nextQueuepos = 0;
if (Continue && Loop && index == -1)
{
IsFinish = true;
nextQueuepos = -1;
Timing.RunCoroutine(Playback(nextQueuepos));
OnFinishedTrack?.Invoke(this, CurrentPlay, index == -1, ref nextQueuepos);
Expand All @@ -341,12 +364,18 @@ public virtual IEnumerator<float> Playback(int position)

if (Continue && AudioToPlay.Count >= 1)
{
IsFinish = true;
Timing.RunCoroutine(Playback(nextQueuepos));
OnFinishedTrack?.Invoke(this, CurrentPlay, index == -1, ref nextQueuepos);
yield break;
}


IsFinish = true;
OnFinishedTrack?.Invoke(this, CurrentPlay, index == -1, ref nextQueuepos);
if (AutoClear)
{
OnDestroy();
}
}

public virtual void Update()
Expand All @@ -367,18 +396,18 @@ public virtual void Update()

if (LogDebug)
Log.Debug($"2 {toCopy} {allowedSamples} {samplesPerSecond} {StreamBuffer.Count} {PlaybackBuffer.Length} {PlaybackBuffer.WriteHead}");

allowedSamples -= toCopy;

while (PlaybackBuffer.Length >= 480)
{
PlaybackBuffer.ReadTo(SendBuffer, (long)480, 0L);
int dataLen = Encoder.Encode(SendBuffer, EncodedBuffer, 480);

foreach (var plr in ReferenceHub.AllHubs)
{
if (plr.connectionToClient == null || (BroadcastTo.Count >= 1 && !BroadcastTo.Contains(plr.PlayerId))) continue;

plr.connectionToClient.Send(new VoiceMessage(Owner, BroadcastChannel, EncodedBuffer, dataLen, false));
}
}
Expand Down
Loading