mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-09 23:34:06 +02:00
Add WIP video player for MP4s
This commit is contained in:
commit
58cc7ea10d
@ -114,6 +114,10 @@ public void ScreenshotTweet(string html, int width, int height){
|
||||
form.InvokeAsyncSafe(() => form.OnTweetScreenshotReady(html, width, height));
|
||||
}
|
||||
|
||||
public void PlayVideo(string url){
|
||||
form.InvokeAsyncSafe(() => form.PlayVideo(url));
|
||||
}
|
||||
|
||||
public void FixClipboard(){
|
||||
form.InvokeAsyncSafe(WindowsUtils.ClipboardStripHtmlStyles);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Notification.Screenshot;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Other.Media;
|
||||
using TweetDuck.Core.Other.Settings;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
@ -58,6 +59,7 @@ public bool IsWaiting{
|
||||
|
||||
private TweetScreenshotManager notificationScreenshotManager;
|
||||
private SoundNotification soundNotification;
|
||||
private VideoPlayer videoPlayer;
|
||||
|
||||
public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings){
|
||||
InitializeComponent();
|
||||
@ -506,6 +508,19 @@ public void PlayNotificationSound(){
|
||||
soundNotification.Play(Config.NotificationSoundPath);
|
||||
}
|
||||
|
||||
public void PlayVideo(string url){
|
||||
if (videoPlayer == null){
|
||||
videoPlayer = new VideoPlayer(this);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(url)){
|
||||
videoPlayer.Launch(url);
|
||||
}
|
||||
else{
|
||||
videoPlayer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTweetScreenshotReady(string html, int width, int height){
|
||||
if (notificationScreenshotManager == null){
|
||||
notificationScreenshotManager = new TweetScreenshotManager(this, plugins);
|
||||
|
70
Core/Other/Media/VideoPlayer.cs
Normal file
70
Core/Other/Media/VideoPlayer.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDuck.Core.Other.Media{
|
||||
class VideoPlayer{
|
||||
private readonly string PlayerExe = Path.Combine(Program.ProgramPath, "TweetDuck.Video.exe");
|
||||
|
||||
private readonly Form owner;
|
||||
private Process currentProcess;
|
||||
|
||||
public VideoPlayer(Form owner){
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void Launch(string url){
|
||||
Close();
|
||||
|
||||
try{
|
||||
if ((currentProcess = Process.Start(new ProcessStartInfo{
|
||||
FileName = PlayerExe,
|
||||
Arguments = $"{owner.Handle} \"{url}\"",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true
|
||||
})) != null){
|
||||
currentProcess.EnableRaisingEvents = true;
|
||||
currentProcess.Exited += process_Exited;
|
||||
|
||||
#if DEBUG
|
||||
currentProcess.BeginOutputReadLine();
|
||||
currentProcess.OutputDataReceived += (sender, args) => Debug.WriteLine("VideoPlayer: "+args.Data);
|
||||
#endif
|
||||
}
|
||||
}catch(Exception e){
|
||||
Program.Reporter.HandleException("Video Playback Error", "Error launching video player.", true, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close(){
|
||||
if (currentProcess != null){
|
||||
currentProcess.Exited -= process_Exited;
|
||||
|
||||
try{
|
||||
currentProcess.Kill();
|
||||
}catch{
|
||||
// kill me instead then
|
||||
}
|
||||
|
||||
currentProcess.Dispose();
|
||||
currentProcess = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void process_Exited(object sender, EventArgs e){
|
||||
switch(currentProcess.ExitCode){
|
||||
case 2: // CODE_LAUNCH_FAIL
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case 3: // CODE_MEDIA_ERROR
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
|
||||
currentProcess.Dispose();
|
||||
currentProcess = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -789,20 +789,52 @@
|
||||
}
|
||||
|
||||
//
|
||||
// Block: Setup unsupported video element hook.
|
||||
// Block: Setup video player hooks.
|
||||
//
|
||||
(function(){
|
||||
var cancelModal = false;
|
||||
var playVideo = function(url){
|
||||
$('<div class="ovl" style="display:block"></div>').click(function(){
|
||||
$TD.playVideo(null);
|
||||
$(this).remove();
|
||||
}).appendTo(app);
|
||||
|
||||
$TD.playVideo(url);
|
||||
};
|
||||
|
||||
app.delegate(".js-gif-play", "click", function(e){
|
||||
let src = $(this).closest(".js-media-gif-container").find("video").attr("src");
|
||||
|
||||
if (src){
|
||||
playVideo(src);
|
||||
}
|
||||
else{
|
||||
let parent = $(e.target).closest(".js-tweet").first();
|
||||
let link = (parent.hasClass("tweet-detail") ? parent.find("a[rel='url']") : parent.find("time").first().children("a")).first();
|
||||
$TD.openBrowser(link.attr("href"));
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
if (!ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet") ||
|
||||
!ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer") ||
|
||||
!ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused"))return;
|
||||
|
||||
var cancelModal = false;
|
||||
|
||||
TD.components.MediaGallery.prototype._loadTweet = appendToFunction(TD.components.MediaGallery.prototype._loadTweet, function(){
|
||||
let media = this.chirp.getMedia().find(media => media.mediaId === this.clickedMediaEntityId);
|
||||
|
||||
if (media && media.isVideo && media.service !== "youtube"){
|
||||
$TD.openBrowser(this.clickedLink);
|
||||
let data = media.chooseVideoVariant();
|
||||
|
||||
if (data.content_type === "video/mp4"){
|
||||
playVideo(data.url);
|
||||
}
|
||||
else{
|
||||
$TD.openBrowser(this.clickedLink);
|
||||
}
|
||||
|
||||
cancelModal = true;
|
||||
}
|
||||
});
|
||||
@ -816,14 +848,6 @@
|
||||
|
||||
TD.ui.Column.prototype.playGifIfNotManuallyPaused = function(){};
|
||||
TD.mustaches["status/media_thumb.mustache"] = TD.mustaches["status/media_thumb.mustache"].replace("is-gif", "is-gif is-paused");
|
||||
|
||||
app.delegate(".js-gif-play", "click", function(e){
|
||||
let parent = $(e.target).closest(".js-tweet").first();
|
||||
let link = (parent.hasClass("tweet-detail") ? parent.find("a[rel='url']") : parent.find("time").first().children("a")).first();
|
||||
|
||||
$TD.openBrowser(link.attr("href"));
|
||||
e.stopPropagation();
|
||||
});
|
||||
})();
|
||||
|
||||
//
|
||||
|
@ -142,6 +142,7 @@
|
||||
<Compile Include="Core\Other\FormPlugins.Designer.cs">
|
||||
<DependentUpon>FormPlugins.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Core\Other\Media\VideoPlayer.cs" />
|
||||
<Compile Include="Core\Other\Settings\Dialogs\DialogSettingsCSS.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@ -345,6 +346,10 @@
|
||||
<Project>{b10b0017-819e-4f71-870f-8256b36a26aa}</Project>
|
||||
<Name>TweetDuck.Browser</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="video\TweetDuck.Video\TweetDuck.Video.csproj">
|
||||
<Project>{278b2d11-402d-44b6-b6a1-8fa67db65565}</Project>
|
||||
<Name>TweetDuck.Video</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "tests\UnitTest
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Audio", "lib\TweetLib.Audio\TweetLib.Audio.csproj", "{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetDuck.Video", "video\TweetDuck.Video\TweetDuck.Video.csproj", "{278B2D11-402D-44B6-B6A1-8FA67DB65565}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
@ -32,6 +34,10 @@ Global
|
||||
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Debug|x86.Build.0 = Debug|x86
|
||||
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Release|x86.ActiveCfg = Release|x86
|
||||
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Release|x86.Build.0 = Release|x86
|
||||
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Debug|x86.Build.0 = Debug|x86
|
||||
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Release|x86.ActiveCfg = Release|x86
|
||||
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
17
video/TweetDuck.Video/ControlWMP.cs
Normal file
17
video/TweetDuck.Video/ControlWMP.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using WMPLib;
|
||||
|
||||
namespace TweetDuck.Video{
|
||||
[DesignTimeVisible(true)]
|
||||
[Clsid("{6bf52a52-394a-11d3-b153-00c04f79faa6}")]
|
||||
class ControlWMP : AxHost{
|
||||
public WindowsMediaPlayer Ocx { get; private set; }
|
||||
|
||||
public ControlWMP() : base("6bf52a52-394a-11d3-b153-00c04f79faa6"){}
|
||||
|
||||
protected override void AttachInterfaces(){
|
||||
Ocx = (WindowsMediaPlayer)GetOcx();
|
||||
}
|
||||
}
|
||||
}
|
96
video/TweetDuck.Video/FormPlayer.Designer.cs
generated
Normal file
96
video/TweetDuck.Video/FormPlayer.Designer.cs
generated
Normal file
@ -0,0 +1,96 @@
|
||||
namespace TweetDuck.Video {
|
||||
partial class FormPlayer {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.player = new TweetDuck.Video.ControlWMP();
|
||||
this.timer = new System.Windows.Forms.Timer(this.components);
|
||||
this.trackBarVolume = new System.Windows.Forms.TrackBar();
|
||||
((System.ComponentModel.ISupportInitialize)(this.player)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// player
|
||||
//
|
||||
this.player.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.player.Enabled = true;
|
||||
this.player.Location = new System.Drawing.Point(0, 0);
|
||||
this.player.Name = "player";
|
||||
this.player.Size = new System.Drawing.Size(236, 120);
|
||||
this.player.TabIndex = 0;
|
||||
//
|
||||
// timer
|
||||
//
|
||||
this.timer.Interval = 10;
|
||||
this.timer.Tick += new System.EventHandler(this.timer_Tick);
|
||||
//
|
||||
// trackBarVolume
|
||||
//
|
||||
this.trackBarVolume.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.trackBarVolume.AutoSize = false;
|
||||
this.trackBarVolume.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.trackBarVolume.Location = new System.Drawing.Point(72, 94);
|
||||
this.trackBarVolume.Maximum = 100;
|
||||
this.trackBarVolume.Name = "trackBarVolume";
|
||||
this.trackBarVolume.Size = new System.Drawing.Size(164, 26);
|
||||
this.trackBarVolume.SmallChange = 5;
|
||||
this.trackBarVolume.TabIndex = 1;
|
||||
this.trackBarVolume.TickFrequency = 10;
|
||||
this.trackBarVolume.TickStyle = System.Windows.Forms.TickStyle.None;
|
||||
this.trackBarVolume.Visible = false;
|
||||
this.trackBarVolume.ValueChanged += new System.EventHandler(this.trackBarVolume_ValueChanged);
|
||||
this.trackBarVolume.MouseUp += new System.Windows.Forms.MouseEventHandler(this.trackBarVolume_MouseUp);
|
||||
//
|
||||
// FormPlayer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(236, 120);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.trackBarVolume);
|
||||
this.Controls.Add(this.player);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormPlayer";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "TweetDuck Video";
|
||||
this.Load += new System.EventHandler(this.FormPlayer_Load);
|
||||
((System.ComponentModel.ISupportInitialize)(this.player)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private ControlWMP player;
|
||||
private System.Windows.Forms.Timer timer;
|
||||
private System.Windows.Forms.TrackBar trackBarVolume;
|
||||
}
|
||||
}
|
||||
|
111
video/TweetDuck.Video/FormPlayer.cs
Normal file
111
video/TweetDuck.Video/FormPlayer.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using WMPLib;
|
||||
|
||||
namespace TweetDuck.Video{
|
||||
partial class FormPlayer : Form{
|
||||
private readonly IntPtr ownerHandle;
|
||||
private readonly string videoUrl;
|
||||
|
||||
private bool isPaused;
|
||||
|
||||
public FormPlayer(IntPtr handle, string url){
|
||||
InitializeComponent();
|
||||
|
||||
this.ownerHandle = handle;
|
||||
this.videoUrl = url;
|
||||
|
||||
player.Ocx.enableContextMenu = false;
|
||||
player.Ocx.uiMode = "none";
|
||||
player.Ocx.settings.setMode("loop", true);
|
||||
|
||||
player.Ocx.MediaChange += player_MediaChange;
|
||||
player.Ocx.MediaError += player_MediaError;
|
||||
|
||||
trackBarVolume.Value = 25; // changes player volume
|
||||
|
||||
Application.AddMessageFilter(new MessageFilter(this));
|
||||
}
|
||||
|
||||
// Events
|
||||
|
||||
private void FormPlayer_Load(object sender, EventArgs e){
|
||||
player.Ocx.URL = videoUrl;
|
||||
}
|
||||
|
||||
private void timer_Tick(object sender, EventArgs e){
|
||||
if (NativeMethods.GetWindowRect(ownerHandle, out NativeMethods.RECT rect)){
|
||||
int width = rect.Right-rect.Left+1;
|
||||
int height = rect.Bottom-rect.Top+1;
|
||||
IWMPMedia media = player.Ocx.currentMedia;
|
||||
|
||||
ClientSize = new Size(Math.Min(media.imageSourceWidth, width*3/4), Math.Min(media.imageSourceHeight, height*3/4));
|
||||
Location = new Point(rect.Left+(width-ClientSize.Width)/2, rect.Top+(height-ClientSize.Height+SystemInformation.CaptionHeight)/2);
|
||||
|
||||
trackBarVolume.Visible = ClientRectangle.Contains(PointToClient(Cursor.Position)) || trackBarVolume.Focused;
|
||||
}
|
||||
else{
|
||||
Environment.Exit(Program.CODE_OWNER_GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void player_MediaChange(object item){
|
||||
timer.Start();
|
||||
Cursor.Current = Cursors.Default;
|
||||
NativeMethods.SetWindowOwner(Handle, ownerHandle);
|
||||
Marshal.ReleaseComObject(item);
|
||||
}
|
||||
|
||||
private void player_MediaError(object pMediaObject){
|
||||
Marshal.ReleaseComObject(pMediaObject);
|
||||
Environment.Exit(Program.CODE_MEDIA_ERROR);
|
||||
}
|
||||
|
||||
private void trackBarVolume_ValueChanged(object sender, EventArgs e){
|
||||
player.Ocx.settings.volume = trackBarVolume.Value;
|
||||
}
|
||||
|
||||
private void trackBarVolume_MouseUp(object sender, MouseEventArgs e){
|
||||
player.Focus();
|
||||
}
|
||||
|
||||
// Controls & messages
|
||||
|
||||
private void TogglePause(){
|
||||
if (isPaused){
|
||||
player.Ocx.controls.play();
|
||||
}
|
||||
else{
|
||||
player.Ocx.controls.pause();
|
||||
}
|
||||
|
||||
isPaused = !isPaused;
|
||||
}
|
||||
|
||||
internal class MessageFilter : IMessageFilter{
|
||||
private readonly FormPlayer form;
|
||||
|
||||
public MessageFilter(FormPlayer form){
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
bool IMessageFilter.PreFilterMessage(ref Message m){
|
||||
if (m.Msg == 0x0201){ // WM_LBUTTONDOWN
|
||||
Point cursor = form.PointToClient(Cursor.Position);
|
||||
|
||||
if (!(cursor.X >= form.trackBarVolume.Location.X && cursor.Y >= form.trackBarVolume.Location.Y)){
|
||||
form.TogglePause();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (m.Msg == 0x0203 || (m.Msg == 0x0100 && m.WParam.ToInt32() == 0x20)){ // WM_LBUTTONDBLCLK, WM_KEYDOWN, VK_SPACE
|
||||
form.TogglePause();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
video/TweetDuck.Video/NativeMethods.cs
Normal file
35
video/TweetDuck.Video/NativeMethods.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TweetDuck.Video{
|
||||
static class NativeMethods{
|
||||
private const int GWL_HWNDPARENT = -8;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
public static void SetWindowOwner(IntPtr child, IntPtr owner){
|
||||
SetWindowLong(child, GWL_HWNDPARENT, owner);
|
||||
/*
|
||||
* "You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window"
|
||||
*
|
||||
* ...which I'm not sure they're saying because this is completely unsupported and causes demons to come out of sewers
|
||||
* ...or because GWL_HWNDPARENT actually changes the OWNER and is therefore NOT changing the parent of a child window
|
||||
*
|
||||
* ...so technically, this is following the documentation to the word.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
39
video/TweetDuck.Video/Program.cs
Normal file
39
video/TweetDuck.Video/Program.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDuck.Video{
|
||||
static class Program{
|
||||
// referenced in VideoPlayer
|
||||
public const int CODE_INVALID_ARGS = 1;
|
||||
public const int CODE_LAUNCH_FAIL = 2;
|
||||
public const int CODE_MEDIA_ERROR = 3;
|
||||
public const int CODE_OWNER_GONE = 4;
|
||||
|
||||
[STAThread]
|
||||
private static int Main(string[] args){
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
IntPtr ownerHandle;
|
||||
string videoUrl;
|
||||
|
||||
try{
|
||||
ownerHandle = new IntPtr(int.Parse(args[0], NumberStyles.Integer, CultureInfo.InvariantCulture));
|
||||
videoUrl = new Uri(args[1], UriKind.Absolute).AbsoluteUri;
|
||||
}catch{
|
||||
return CODE_INVALID_ARGS;
|
||||
}
|
||||
|
||||
try{
|
||||
Application.Run(new FormPlayer(ownerHandle, videoUrl));
|
||||
}catch(Exception e){
|
||||
// TODO
|
||||
Console.Out.WriteLine(e.Message);
|
||||
return CODE_LAUNCH_FAIL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
35
video/TweetDuck.Video/Properties/AssemblyInfo.cs
Normal file
35
video/TweetDuck.Video/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TweetDuck Video")]
|
||||
[assembly: AssemblyDescription("TweetDuck Video")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TweetDuck.Video")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("278b2d11-402d-44b6-b6a1-8fa67db65565")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
69
video/TweetDuck.Video/TweetDuck.Video.csproj
Normal file
69
video/TweetDuck.Video/TweetDuck.Video.csproj
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{278B2D11-402D-44B6-B6A1-8FA67DB65565}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>TweetDuck.Video</RootNamespace>
|
||||
<AssemblyName>TweetDuck.Video</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<ResolveComReferenceSilent>True</ResolveComReferenceSilent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>none</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ControlWMP.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormPlayer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormPlayer.Designer.cs">
|
||||
<DependentUpon>FormPlayer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="NativeMethods.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="WMPLib">
|
||||
<Guid>{6BF52A50-394A-11D3-B153-00C04F79FAA6}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user