mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-17 03:15:47 +02:00
Implement video player in TweetDeck
This commit is contained in:
parent
54d12686af
commit
8b676fe6ce
@ -114,6 +114,10 @@ public void ScreenshotTweet(string html, int width, int height){
|
|||||||
form.InvokeAsyncSafe(() => form.OnTweetScreenshotReady(html, width, height));
|
form.InvokeAsyncSafe(() => form.OnTweetScreenshotReady(html, width, height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PlayVideo(string url){
|
||||||
|
form.InvokeAsyncSafe(() => form.PlayVideo(url));
|
||||||
|
}
|
||||||
|
|
||||||
public void FixClipboard(){
|
public void FixClipboard(){
|
||||||
form.InvokeAsyncSafe(WindowsUtils.ClipboardStripHtmlStyles);
|
form.InvokeAsyncSafe(WindowsUtils.ClipboardStripHtmlStyles);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
using TweetDuck.Core.Notification;
|
using TweetDuck.Core.Notification;
|
||||||
using TweetDuck.Core.Notification.Screenshot;
|
using TweetDuck.Core.Notification.Screenshot;
|
||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
|
using TweetDuck.Core.Other.Media;
|
||||||
using TweetDuck.Core.Other.Settings;
|
using TweetDuck.Core.Other.Settings;
|
||||||
using TweetDuck.Core.Utils;
|
using TweetDuck.Core.Utils;
|
||||||
using TweetDuck.Plugins;
|
using TweetDuck.Plugins;
|
||||||
@ -58,6 +59,7 @@ public bool IsWaiting{
|
|||||||
|
|
||||||
private TweetScreenshotManager notificationScreenshotManager;
|
private TweetScreenshotManager notificationScreenshotManager;
|
||||||
private SoundNotification soundNotification;
|
private SoundNotification soundNotification;
|
||||||
|
private VideoPlayer videoPlayer;
|
||||||
|
|
||||||
public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings){
|
public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings){
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -506,6 +508,19 @@ public void PlayNotificationSound(){
|
|||||||
soundNotification.Play(Config.NotificationSoundPath);
|
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){
|
public void OnTweetScreenshotReady(string html, int width, int height){
|
||||||
if (notificationScreenshotManager == null){
|
if (notificationScreenshotManager == null){
|
||||||
notificationScreenshotManager = new TweetScreenshotManager(this, plugins);
|
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(){
|
(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") ||
|
if (!ensurePropertyExists(TD, "components", "MediaGallery", "prototype", "_loadTweet") ||
|
||||||
!ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer") ||
|
!ensurePropertyExists(TD, "components", "BaseModal", "prototype", "setAndShowContainer") ||
|
||||||
!ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused"))return;
|
!ensurePropertyExists(TD, "ui", "Column", "prototype", "playGifIfNotManuallyPaused"))return;
|
||||||
|
|
||||||
|
var cancelModal = false;
|
||||||
|
|
||||||
TD.components.MediaGallery.prototype._loadTweet = appendToFunction(TD.components.MediaGallery.prototype._loadTweet, function(){
|
TD.components.MediaGallery.prototype._loadTweet = appendToFunction(TD.components.MediaGallery.prototype._loadTweet, function(){
|
||||||
let media = this.chirp.getMedia().find(media => media.mediaId === this.clickedMediaEntityId);
|
let media = this.chirp.getMedia().find(media => media.mediaId === this.clickedMediaEntityId);
|
||||||
|
|
||||||
if (media && media.isVideo && media.service !== "youtube"){
|
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;
|
cancelModal = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -816,14 +848,6 @@
|
|||||||
|
|
||||||
TD.ui.Column.prototype.playGifIfNotManuallyPaused = function(){};
|
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");
|
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">
|
<Compile Include="Core\Other\FormPlugins.Designer.cs">
|
||||||
<DependentUpon>FormPlugins.cs</DependentUpon>
|
<DependentUpon>FormPlugins.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Core\Other\Media\VideoPlayer.cs" />
|
||||||
<Compile Include="Core\Other\Settings\Dialogs\DialogSettingsCSS.cs">
|
<Compile Include="Core\Other\Settings\Dialogs\DialogSettingsCSS.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
namespace TweetDuck.Video{
|
namespace TweetDuck.Video{
|
||||||
static class Program{
|
static class Program{
|
||||||
|
// referenced in VideoPlayer
|
||||||
public const int CODE_INVALID_ARGS = 1;
|
public const int CODE_INVALID_ARGS = 1;
|
||||||
public const int CODE_LAUNCH_FAIL = 2;
|
public const int CODE_LAUNCH_FAIL = 2;
|
||||||
public const int CODE_MEDIA_ERROR = 3;
|
public const int CODE_MEDIA_ERROR = 3;
|
||||||
|
Loading…
Reference in New Issue
Block a user