Amazon Polly를 이용해서 TTS를 만드는 간단한 셈플을 만들어 보도록 하겠습니다.


완성이되면 이런 화면에서 한글을 입력하고 폴리야~ 버튼을 클릭하면 설현(?) 목소리로 내용을 읽어 줍니다.



1. 준비


1) AWS를 이용하기 때문에 Amazon Web Service 계정이 필요합니다.

저도 없어서 새로 만들었습니다.


https://aws.amazon.com/ko/polly/


이 페이지를 상단에 무료 계정 생성하기 버튼을 클릭해서 계정을 만들면 됩니다.


2) 계정을 만들고 나면, IAM 관리자 및 계정을 만들어 주어야 합니다.


https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/getting-started_create-admin-group.html


이 페이지를 참고하셔서 IAM 계정을 생성하고, 그룹도 추가해 주시면 됩니다.


3) Polly 서비스를 사용하기 위해서 AccessKeyID와 SecretAccessKey가 필요합니다.


https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/id_credentials_access-keys.html


이 페이지를 참고하시면 만드실 수 있습니다.



2. 프로젝트 생성


Visual Stduio 2017를 실행하고, Windows Template Studio를 이용해서 단일 화면 프로젝트를 생성 했습니다.




3. NuGet Package 설치


AWSSDK.Core, AWSSDK.Polly 2개의 패키지를 선택해서 설치 합니다.



4. MainPage.xaml


            <StackPanel Grid.Row="1" Grid.Column="1">
                <TextBox Header="한글을 입력하세요" Text="{Binding InputText, Mode=TwoWay}"/>
                <Button Content="폴리야" Command="{Binding TTSCommand}"/>
                <MediaElement x:Name="MediaElement" RealTimePlayback="True">
                    <interactivity:Interaction.Behaviors>
                        <core:EventTriggerBehavior EventName="MediaEnded">
                            <core:InvokeCommandAction Command="{Binding MediaEndedCommand}"/>
                        </core:EventTriggerBehavior>
                        <behaviors:MediaBehavior Stream="{Binding RandomAccessStream, Mode=TwoWay}"/>
                    </interactivity:Interaction.Behaviors>
                </MediaElement>
            </StackPanel>



일반적인 코드입니다. 여기서 사용된 MediaBehavior는 지난번에 공유했던 내용이라 설명은 생략 합니다.


내부 코드는 좀 변경이 되었으니 맨 아래 공유해드리는 소스를 참고 하시면 될 것 같습니다.



5. MainViewModel.cs


        /// <summary>
        ///     TTS 커맨드 실행
        /// </summary>
        private async void ExecuteTTSCommand()
        {
            if (string.IsNullOrEmpty(InputText)) return;

            //폴리 클라이언트 생성
            var pc = new AmazonPollyClient("AccessKeyID를 입력하세요", "SecretAccessKey를 입력하세요"
                , RegionEndpoint.APNortheast2);

            //요청 생성
            var sreq = new SynthesizeSpeechRequest
            {
                Text = $"<speak>{InputText}</speak>",
                OutputFormat = OutputFormat.Mp3,
                VoiceId = VoiceId.Seoyeon,
                LanguageCode = "ko-KR",
                TextType = TextType.Ssml
            };

            InputText = string.Empty;

            //서비스 요청
            var sres = await pc.SynthesizeSpeechAsync(sreq);

            //서비스 요청 결과 확인
            if (sres.HttpStatusCode != HttpStatusCode.OK)
                return;

            //파일명 생성
            var fileName = $@"{ApplicationData.Current.LocalFolder.Path}\{DateTime.Now:yyMMddhhmmss}.mp3";
            //파일에 AudioStream 쓰기
            using (var fileStream = File.Create(fileName))
            {
                sres.AudioStream.CopyTo(fileStream);
                fileStream.Flush();
                fileStream.Close();
            }
            //생성된 파일을 가져오기
            var file = await StorageFile.GetFileFromPathAsync(fileName);
            //파일을 열어서 RandomAccessStream 프로퍼티에 입력
            RandomAccessStream = await file.OpenAsync(FileAccessMode.Read);

            //RandomAccessStream과 바인딩이 되어있는 MediaBehavior에서 MediaPlayer를 통해서 재생
        }


리즌 종류는 여기서 확인하세용

https://docs.aws.amazon.com/ko_kr/general/latest/gr/rande.html



6. 다운 받은 셈플 보이스



7. 소스


https://github.com/kaki104/AWSSamples



블로그 이미지

MVP kaki104

* Microsoft MVP - Windows Development 2014 ~ 2019 5ring * LINE : kaki104 * facebook : https://www.facebook.com/kaki104 https://www.facebook.com/groups/w10app/

Tag aws, Polly

2018 청년에코 메이커 챌린지 행사에 멘토로 참석한 후기를 이제 올립니다.


행사 장소는 부산진구 호천마을이고 2018.8.10-8.11일까지 진행했습니다.


저는 금요일 저녁에 KTX를 타고 내려가서 토요일 하루 종일 참석을 했네요.


행사 장소가 호천 생활 문화 센터였는데, 처음 가본 부산 진구인지라..멋있는 곳이라고 생각했네요 


부산 시내 중고등학교 10개 팀이 참가해서 자연 친화 에너지를 이용한 건축물을 만드는 과정을 진행했습니다. 


오전 10시쯤 부터 시작했는데 몇시간 지나지 않아 건축물(?)이 만들어지는 모습이 신기하네요


오후 4시 반쯤 각 팀에서 만든 건축물에 대한 설명을 진행하고 있습니다.


하루종일 행사장에서 학생들과 함께 이야기하며, 만드는 과정을 지켜보았는데, 작품을 만드는 열정이 매우 높아서 놀랐습니다. 앞으로 이 학생들이 성인이 되어서도 환경을 생각하는 마음을 잊지 않고 더 열심히 정진하면 좋은 결과가 만들어 질 것 같습니다.


시간이 넉넉하지 않아서, S/W적인 부분에 대한 지원을 거의 하지 못했지만, 학생들의 작품 보강을 한다고 하면, 다시 참석해서 열심히 알려주고 싶습니다.


고생하신 환경단체 여러분들과 이런 좋은 행사를 알려주신 서인수 대표님께 감사드립니다.


블로그 이미지

MVP kaki104

* Microsoft MVP - Windows Development 2014 ~ 2019 5ring * LINE : kaki104 * facebook : https://www.facebook.com/kaki104 https://www.facebook.com/groups/w10app/

페이스북 그룹에 올려주신 문의 내용에 맞는 셈플을 만들어 보았습니다.
https://www.facebook.com/groups/w10app 



Q. 안녕하세요.
숫자 키패드에 마우스 클릭이나 키보드 둘 다 입력이 가능하도록 mvvm을 사용하여 구현하고 싶습니다.
기존 event-driven에서는 두 개의 event를 구현해서 button에 연결하면 되었는데,이를 mvvm으로 하려니 문제가 생겼네요.
제가 알기로는 mvvm하에서는 xaml상에서 버튼 컨트롤에 command로 연결해줘야 하는 것으로 알고 있습니다. 즉 버튼 컨트롤에 하나의 이벤트만 커맨드로 처리할 수 있다고 저는 알고 있는데, 이러면 이벤트 두 개 중 하나만 구현 가능한 건가요?
mvvm하에서도 event-driven과 같이 마우스 클릭이나 키보드 둘 다 사용 가능하게 구현하고 싶은데, 이를 어떻게 구현해야 하나요?



A. 버튼에 단축키를 설정하면 간단하게 해결하실 수 있습니다.


참고

https://docs.microsoft.com/en-us/windows/uwp/design/input/keyboard-accelerators


                <!--숫자 키패드는 키를 추가해줘야 합니다.-->
                <Button Grid.Column="0" Grid.Row="0" Content="1"
                        Command="{Binding InputCommand}" CommandParameter="1">
                    <Button.KeyboardAccelerators>
                        <KeyboardAccelerator Key="Number1" />
                    </Button.KeyboardAccelerators>

                </Button>


1버튼에 숫자키1를 단축키로 설정하고, InputCommand를 실행 합니다. 실행할 때 CommandParameter로 1을 넘겨 줍니다.



        private void Init()
        {
            InputNumbers = "0";
            InputCommand = new RelayCommand<object>(ExecuteInputCommand);
        }

        /// <summary>
        ///     인풋 커맨드 실행
        /// </summary>
        /// <param name="obj"></param>
        private void ExecuteInputCommand(object obj)
        {
            if (!(obj is string number)) return;

            
            var num = int.Parse(InputNumbers.Replace(",", ""));

            //backspace키는 shell에서 사용하고 있기 때문에 사용이 않되는 듯..
            switch (number)
            {
                case "*":
                    break;
                case "B":
                    num = num.ToString().Length == 1
                        ? 0
                        : int.Parse(num.ToString().Substring(0, num.ToString().Length - 1));
                    break;
                default:
                    num = int.Parse(num + number);
                    break;
            }

            InputNumbers = string.Format("{0:N0}", num);
        }


InputNumbers라는 프로퍼티에 숫자를 string.Format을 이용해서 변환을 해서 집어 넣습니다.


그러면 3자리마다 컴마가 입력됩니다. 숫자 FormatString에 대한 자세한 사항은 검색을 이용하면 쉽게 찾으실 수 있습니다.


BackSpace키는 쉘에서 네비게이션 Back을 하는 키로 사용되고 있어서 B키를 하나 지우는 키로 사용했습니다. 


Windows Tempalte Studio를 이용해서 만든 앱이 아니라면, 사용이 가능할 것이라고 생각됩니다.


자세한 내용은 소스를 참고하세요


깃허브 소스

https://github.com/kaki104/BasicSamples


블로그 이미지

MVP kaki104

* Microsoft MVP - Windows Development 2014 ~ 2019 5ring * LINE : kaki104 * facebook : https://www.facebook.com/kaki104 https://www.facebook.com/groups/w10app/

UWP앱들을 보면 검색 버튼을 클릭하면 택스트 박스가 출력되는 UI를 자주 볼 수 있습니다.


음..기본으로 제공되는 줄 알았는데..그러지는 않더군요..ㅋㅋ

간단하게 만들어보았습니다.


1. XAML


<Page>

    <Page.Resources>

        <Style x:Key="SearchBoxStyle" TargetType="FlyoutPresenter">
            <Setter Property="Margin" Value="78,0,0,0"/>
            <Setter Property="Padding" Value="5"/>
            <Setter Property="Height" Value="50"/>
        </Style>

    </Page.Resources>

    <Grid>


        <CommandBar Background="Transparent" IsOpen="False" DefaultLabelPosition="Right">
            <AppBarButton Icon="Find" Label="Find">
                <AppBarButton.Flyout>
                    <Flyout Placement="Left" FlyoutPresenterStyle="{StaticResource SearchBoxStyle}"
                            Opened="FlyoutBase_OnOpened">
                        <AutoSuggestBox x:Name="SuggestBox" PlaceholderText="Input words to search" AllowFocusOnInteraction="True" />
                    </Flyout>
                </AppBarButton.Flyout>
            </AppBarButton>

            <AppBarButton Icon="Add" Label="Add" Command="{Binding AddCommand}"/>
        </CommandBar>

    </Grid>

</Page>



2. XAML.CS


        private void FlyoutBase_OnOpened(object sender, object e)
        {
            SuggestBox.Focus(FocusState.Programmatic);
        }



3. 설명


여기서 핵심은 AppBarButton의 Flyout을 이용해서 툴팁 같은 팝업을 출력하는 것입니다. 그 내부에 메뉴도 넣을 수 있고, 머 여러가지로 활용을 하는데.. 이번에는 AutoSuggestBox를 집어 넣은 것입니다.


AutoSuggestBox가 Windows 10의 기본 검색 컨트롤이라고 하네요..음..SearchBox 컨트롤도 존재하지만, 이전 버전에서 사용되는 컨트롤이라...


검색 버튼을 누르기전




검색 버튼을 누른 후


검색 버튼을 누른 후 포커스를 넣기 위해서 CS에서 코딩을 하나 했습니다.

CS 코딩이 싫은 분들은 Behavior를 만들어서 사용하시면 됩니다.


블로그 이미지

MVP kaki104

* Microsoft MVP - Windows Development 2014 ~ 2019 5ring * LINE : kaki104 * facebook : https://www.facebook.com/kaki104 https://www.facebook.com/groups/w10app/

티스토리 툴바