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
29 changes: 27 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ Desktop.ini
*.swp

# Unity
/Library
/[Ll]ibrary
/Logs
/Temp
/[Tt]emp
/[Oo]bj/

/Assets/StreamingAssets/FFmpegOut/Windows/ffmpeg.exe
/Assets/StreamingAssets/FFmpegOut/macOS/ffmpeg
Expand All @@ -20,3 +21,27 @@ Desktop.ini
/*.mov
/*.mp4
/*.webm


# Rider
/.idea/
/Assets/Plugins/Editor/Jetbrains/
/Assets/Plugins/Editor/Jetbrains.meta

# Visual Studio Code
/.vscode/

# Autogenerated VS solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
58 changes: 58 additions & 0 deletions Assets/FFmpegOut/Editor/StreamPresetDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace FFmpegOut.LiveStream
{
[CustomPropertyDrawer(typeof(StreamPreset))]
public class StreamPresetDrawer : PropertyDrawer
{
const int LINES = 3;

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Rect tmpRect = new Rect(
position.x, position.y,
position.width, base.GetPropertyHeight(property, GUIContent.none));

tmpRect.y += base.GetPropertyHeight(property, GUIContent.none) / 2f;
EditorGUI.PropertyField(tmpRect, property);

// starting next line
tmpRect.y += base.GetPropertyHeight(property, GUIContent.none);
StreamPreset p = (StreamPreset) property.enumValueIndex;
string tooltip = string.Empty;
switch (p)
{
case StreamPreset.Udp:
tooltip = @"[udp adress]; e.g. udp://127.0.0.1:10755";
break;
case StreamPreset.Rtp:
tooltip = @"[rtp adress]; e.g. rtp://127.0.0.1:10755";
break;
case StreamPreset.Rtsp:
tooltip = @"[rtsp adress]; e.g. rtsp://127.0.0.1:10755";
break;
case StreamPreset.Hls:
tooltip = @"[http server base url] [htdocs directory path + m3u8 file name extension]; e.g. http://127.0.0.1:8000/ D:\[ServerLocation]\htdocs\stream.m3u8";
break;
case StreamPreset.Hls_ssegment:
tooltip = @"[http server base url] -segment_list [htdocs directory path + m3u8 file name extension] [htdocs directory path + ts file name extension]; e.g. http://127.0.0.185:8000/ -segment_list D:\[ServerLocation]\htdocs\stream.m3u8 D:\[ServerLocation]\htdocs\out%03d.ts";
break;
case StreamPreset.Rtmp:
tooltip = @"[rtmp adress]; e.g. rtmp://127.0.0.1:1935/rtmp_stream/mystream";
break;
}

Rect indentPosition = new Rect(tmpRect);
indentPosition = EditorGUI.PrefixLabel(tmpRect, new GUIContent("Address Example"));
EditorGUI.SelectableLabel(indentPosition, tooltip);
}

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return base.GetPropertyHeight(property, label) * LINES;
}
}
}
11 changes: 11 additions & 0 deletions Assets/FFmpegOut/Editor/StreamPresetDrawer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 17 additions & 5 deletions Assets/FFmpegOut/Runtime/CameraCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace FFmpegOut
{
[AddComponentMenu("FFmpegOut/Camera Capture")]
public sealed class CameraCapture : MonoBehaviour
public class CameraCapture : MonoBehaviour
{
#region Public properties

Expand Down Expand Up @@ -57,6 +57,20 @@ int GetAntiAliasingLevel(Camera camera)
return camera.allowMSAA ? QualitySettings.antiAliasing : 1;
}

#endregion

#region Public members

protected virtual FFmpegSession GetSession( int texWidth, int texHeight )
{
return FFmpegSession.Create(
gameObject.name,
texWidth,
texHeight,
_frameRate, _preset
);
}

#endregion

#region Time-keeping variables
Expand Down Expand Up @@ -145,11 +159,9 @@ void Update()
}

// Start an FFmpeg session.
_session = FFmpegSession.Create(
gameObject.name,
_session = GetSession(
camera.targetTexture.width,
camera.targetTexture.height,
_frameRate, preset
camera.targetTexture.height
);

_startTime = Time.time;
Expand Down
4 changes: 2 additions & 2 deletions Assets/FFmpegOut/Runtime/FFmpegSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace FFmpegOut
{
public sealed class FFmpegSession : System.IDisposable
public class FFmpegSession : System.IDisposable
{
#region Factory methods

Expand Down Expand Up @@ -96,7 +96,7 @@ public void Dispose()
FFmpegPipe _pipe;
Material _blitMaterial;

FFmpegSession(string arguments)
protected FFmpegSession(string arguments)
{
if (!FFmpegPipe.IsAvailable)
Debug.LogWarning(
Expand Down
8 changes: 8 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream/StreamCameraCapture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using UnityEngine;

namespace FFmpegOut.LiveStream
{
public class StreamCameraCapture : CameraCapture
{
[SerializeField] protected StreamPreset _streamPreset;
[SerializeField] protected string _streamAddress;

protected override FFmpegSession GetSession(int texWidth, int texHeight)
{
return StreamFFmpegSession.Create(
texWidth,
texHeight,
frameRate,
preset,
_streamPreset,
_streamAddress);
}
}
}
11 changes: 11 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream/StreamCameraCapture.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream/StreamFFmpegSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace FFmpegOut.LiveStream
{
/// <summary>
/// This FFmpegSession pipes whatever is on stdin to FFmpeg.
/// </summary>
public sealed class StreamFFmpegSession : FFmpegSession
{
private const string UNITY_CAM_TEX_BYTE_FORMAT =
"-pixel_format rgba -colorspace bt709 -f rawvideo -vcodec rawvideo";

private const string FFMPEG_LOGLEVEL = "-loglevel warning";

private StreamFFmpegSession(string arguments) : base(arguments) { }

public static StreamFFmpegSession Create(
int width, int height, float frameRate,
FFmpegPreset encodingPreset, StreamPreset streamPreset,
string address)
{
// pipe:0 corresponds to stdin
string ffmpegArguments =
$"{UNITY_CAM_TEX_BYTE_FORMAT} {FFMPEG_LOGLEVEL} -framerate {frameRate} -video_size {width}x{height} "
+ $"-re -i pipe:0 {encodingPreset.GetOptions()} "
+ $"{streamPreset.GetOptions()} {address}";

return new StreamFFmpegSession(ffmpegArguments);
}
}
}
11 changes: 11 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream/StreamFFmpegSession.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream/StreamPreset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace FFmpegOut.LiveStream
{
public enum StreamPreset
{
Udp,
Rtp,
Rtsp,
Hls,
Hls_ssegment,
Rtmp
}

public static class StreamPresetExtensions
{
public static string GetOptions(this StreamPreset preset)
{
switch (preset)
{
case StreamPreset.Udp:
return "-f mpegts";
case StreamPreset.Rtp:
return "-f rtp_mpegts";
case StreamPreset.Rtsp:
return "-f rtsp";
case StreamPreset.Hls:
return "-f hls -hls_flags delete_segments -hls_init_time 0.5 -hls_time 0.5 -hls_list_size 10 -hls_allow_cache 1 -hls_base_url";
case StreamPreset.Hls_ssegment:
return "-f segment -segment_list_type m3u8 -segment_list_size 10 -segment_list_flags +live -segment_time 1 -segment_wrap 10 -segment_list_entry_prefix";
case StreamPreset.Rtmp:
return "-f flv";
}

return null;
}
}
}
11 changes: 11 additions & 0 deletions Assets/FFmpegOut/Runtime/LiveStream/StreamPreset.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/Plugins.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/Plugins/Editor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file added Assets/Plugins/Editor/.gitkeep
Empty file.
18 changes: 18 additions & 0 deletions Assets/Test/SetTimeNow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;

public class SetTimeNow : MonoBehaviour
{
public Text timeText;

void Update()
{
timeText.text = DateTime.UtcNow.ToString(
"HH:mm:ss.fff",
CultureInfo.InvariantCulture );
}
}
11 changes: 11 additions & 0 deletions Assets/Test/SetTimeNow.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading