|
| 1 | +using Fritz.StreamLib.Core; |
| 2 | +using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction; |
| 3 | +using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction.Models; |
| 4 | +using Microsoft.Extensions.Configuration; |
| 5 | +using System; |
| 6 | +using System.Linq; |
| 7 | +using System.Collections.Generic; |
| 8 | +using System.Collections.Immutable; |
| 9 | +using System.Text; |
| 10 | +using System.Threading.Tasks; |
| 11 | +using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training; |
| 12 | + |
| 13 | +namespace Fritz.Chatbot.Commands |
| 14 | +{ |
| 15 | + public class PredictHatCommand : IBasicCommand |
| 16 | + { |
| 17 | + public string Trigger => "hat"; |
| 18 | + public string Description => "Identify which hat Fritz is wearing"; |
| 19 | + public TimeSpan? Cooldown => TimeSpan.FromSeconds(30); |
| 20 | + |
| 21 | + private string _CustomVisionKey = ""; |
| 22 | + private string _AzureEndpoint = ""; |
| 23 | + private string _TwitchChannel = ""; |
| 24 | + private Guid _AzureProjectId; |
| 25 | + |
| 26 | + private static string _IterationName = ""; |
| 27 | + |
| 28 | + public PredictHatCommand(IConfiguration configuration) |
| 29 | + { |
| 30 | + _CustomVisionKey = configuration["AzureServices:HatDetection:Key"]; |
| 31 | + _AzureEndpoint = configuration["AzureServices:HatDetection:CustomVisionEndpoint"]; |
| 32 | + _TwitchChannel = configuration["StreamServices:Twitch:Channel"]; |
| 33 | + _AzureProjectId = Guid.Parse(configuration["AzureServices:HatDetection:ProjectId"]); |
| 34 | + } |
| 35 | + |
| 36 | + public string TwitchScreenshotUrl => $"https://static-cdn.jtvnw.net/previews-ttv/live_user_{_TwitchChannel}-1280x720.jpg?_="; |
| 37 | + |
| 38 | + |
| 39 | + public async Task Execute(IChatService chatService, string userName, ReadOnlyMemory<char> rhs) |
| 40 | + { |
| 41 | + |
| 42 | + if (string.IsNullOrEmpty(_IterationName)) { |
| 43 | + await IdentifyIterationName(); |
| 44 | + } |
| 45 | + |
| 46 | + var client = new CustomVisionPredictionClient() |
| 47 | + { |
| 48 | + ApiKey = _CustomVisionKey, |
| 49 | + Endpoint = _AzureEndpoint |
| 50 | + }; |
| 51 | + var result = await client.DetectImageUrlWithNoStoreAsync(_AzureProjectId, _IterationName, new ImageUrl(TwitchScreenshotUrl)); |
| 52 | + |
| 53 | + var bestMatch = result.Predictions.OrderByDescending(p => p.Probability).FirstOrDefault(); |
| 54 | + if (bestMatch == null || bestMatch.Probability <= 0.3D) { |
| 55 | + await chatService.SendMessageAsync("No match found for the current hat"); |
| 56 | + // do we store the image? |
| 57 | + return; |
| 58 | + } |
| 59 | + |
| 60 | + await chatService.SendMessageAsync($"I think (with {bestMatch.Probability.ToString("0.0%")} certainty) Jeff is currently wearing his {bestMatch.TagName} hat"); |
| 61 | + |
| 62 | + } |
| 63 | + |
| 64 | + private async Task IdentifyIterationName() |
| 65 | + { |
| 66 | + |
| 67 | + var client = new CustomVisionTrainingClient() { |
| 68 | + ApiKey = _CustomVisionKey, |
| 69 | + Endpoint = _AzureEndpoint |
| 70 | + }; |
| 71 | + |
| 72 | + var iterations = await client.GetIterationsAsync(_AzureProjectId); |
| 73 | + _IterationName = iterations |
| 74 | + .Where(i => !string.IsNullOrEmpty(i.PublishName) && i.Status == "Completed") |
| 75 | + .OrderByDescending(i => i.LastModified).First().PublishName; |
| 76 | + |
| 77 | + } |
| 78 | + } |
| 79 | +} |
0 commit comments