├── LICENSE ├── README.ja.md ├── README.md ├── RecShare.unitypackage ├── RecShare └── Assets │ ├── RecShare.meta │ └── RecShare │ ├── Editor.meta │ ├── Editor │ ├── Images.meta │ ├── Images.xcassets.meta │ ├── Images.xcassets │ │ ├── README.txt │ │ ├── README.txt.meta │ │ ├── twitter_icon.imageset.meta │ │ ├── twitter_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── Contents.json.meta │ │ │ ├── twitter_icon120.png │ │ │ ├── twitter_icon120.png.meta │ │ │ ├── twitter_icon152.png │ │ │ ├── twitter_icon152.png.meta │ │ │ ├── twitter_icon180.png │ │ │ ├── twitter_icon180.png.meta │ │ │ ├── twitter_icon60.png │ │ │ ├── twitter_icon60.png.meta │ │ │ ├── twitter_icon76.png │ │ │ └── twitter_icon76.png.meta │ │ ├── video_icon.imageset.meta │ │ └── video_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── Contents.json.meta │ │ │ ├── video_icon15.png │ │ │ ├── video_icon15.png.meta │ │ │ ├── video_icon30.png │ │ │ ├── video_icon30.png.meta │ │ │ ├── video_icon45.png │ │ │ └── video_icon45.png.meta │ ├── Images │ │ ├── README.txt │ │ ├── README.txt.meta │ │ ├── logo.png │ │ ├── logo.png.meta │ │ ├── logo@2x.png │ │ ├── logo@2x.png.meta │ │ ├── logo@3x.png │ │ ├── logo@3x.png.meta │ │ ├── title.png │ │ ├── title.png.meta │ │ ├── title@2x.png │ │ ├── title@2x.png.meta │ │ ├── title@3x.png │ │ └── title@3x.png.meta │ ├── RecSharePostProcessBuild.cs │ └── RecSharePostProcessBuild.cs.meta │ ├── Plugins.meta │ ├── Plugins │ ├── iOS.meta │ └── iOS │ │ ├── RecShare.meta │ │ └── RecShare │ │ ├── RecShareAppController.h │ │ ├── RecShareAppController.h.meta │ │ ├── RecShareAppController.m │ │ ├── RecShareAppController.m.meta │ │ ├── RecShareManager.h │ │ ├── RecShareManager.h.meta │ │ ├── RecShareManager.mm │ │ ├── RecShareManager.mm.meta │ │ ├── RecSharePlugin.mm │ │ ├── RecSharePlugin.mm.meta │ │ ├── Twitter.meta │ │ ├── Twitter │ │ ├── TweetPresentationController.h │ │ ├── TweetPresentationController.h.meta │ │ ├── TweetPresentationController.m │ │ ├── TweetPresentationController.m.meta │ │ ├── TweetViewController.h │ │ ├── TweetViewController.h.meta │ │ ├── TweetViewController.m │ │ ├── TweetViewController.m.meta │ │ ├── TweetViewController.xib │ │ ├── TweetViewController.xib.meta │ │ ├── TwitterActivity.h │ │ ├── TwitterActivity.h.meta │ │ ├── TwitterActivity.m │ │ ├── TwitterActivity.m.meta │ │ ├── TwitterApiCaller.h │ │ ├── TwitterApiCaller.h.meta │ │ ├── TwitterApiCaller.m │ │ ├── TwitterApiCaller.m.meta │ │ ├── TwitterConfig.h │ │ └── TwitterConfig.h.meta │ │ ├── VideoCreator.h │ │ ├── VideoCreator.h.meta │ │ ├── VideoCreator.m │ │ └── VideoCreator.m.meta │ ├── Sample.meta │ ├── Sample │ ├── Cube.cs │ ├── Cube.cs.meta │ ├── Material.mat │ ├── Material.mat.meta │ ├── Sample.cs │ ├── Sample.cs.meta │ ├── Sample.unity │ └── Sample.unity.meta │ ├── Scripts.meta │ └── Scripts │ ├── Stub.meta │ ├── Stub │ ├── RecShare.cs │ └── RecShare.cs.meta │ ├── iOS.meta │ └── iOS │ ├── RecShare.cs │ └── RecShare.cs.meta └── RecShareSample.unitypackage /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Takayasu Yajima(@tkyaji) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.ja.md: -------------------------------------------------------------------------------- 1 | # UnityRecShare 2 | 3 | Unityでプレイ動画を録画し、共有することができます 4 | 5 | [English](README.md) | 日本語 6 | 7 | 8 | # 対応状況 9 | 10 | * >= Unity 5.3 11 | * >= iOS 8 12 | 13 | (iOSのみ、録音未対応) 14 | 15 | 16 | # 使い方 17 | * `RecShare.unitypackage` をインポート 18 | * サンプルが必要な場合、`RecShareSample.unitypackage` を追加でインポート 19 | 20 | 21 | # API 22 | 23 | ## void RecShare.Initialize() 24 | 25 | 初期処理を実行します。録画実行前に必ず実行が必要です。 26 | 27 | 28 | 29 | ## void RecShare.StartRecording() 30 | 31 | 録画を開始します。`Initialize`を実行済みである必要があります。 32 | 33 | ## void RecShare.StopRecording(Action completion = null) 34 | 35 | 録画を終了します。 36 | 37 | * `completion` 録画終了処理が完了したタイミングで実行されます 38 | 39 | ## void RecShare.PauseRecording 40 | 41 | 録画を一時停止します 42 | 43 | ## void RecShare.ResumeRecording 44 | 45 | `PauseRecording`で一時停止した録画を再開します 46 | 47 | ## bool RecShare.IsRecording 48 | 49 | 録画実行中の場合、`true`を返します 50 | 51 | ## bool RecShare.IsPaused 52 | 53 | `PauseRecording`で録画を一時停止中の場合、`true`を返します 54 | 55 | ## void RecShare.ShowSharingModal(string text = "") 56 | 57 | iOSの共有シートを表示します 58 | 59 | * `text` 共有テキストを指定します 60 | 61 | ## void RecShare.ShowVideoPlayer 62 | 63 | 録画した動画を再生するためのプレイヤーを表示します 64 | 65 | ## string RecShare.GetVideoFilePath 66 | 67 | 録画ファイルのパスを返しします 68 | 69 | ## float RecShare.GetVideoDuration 70 | 71 | 録画時間(秒)を返します。録画実行前、実行中の場合は0を返します。 72 | 73 | ## Texture2D RecShare.GetScreenShot(float seconds) 74 | 75 | 指定した時間(秒)のフレームの画像を取り出し、Texture2Dにして返します。 76 | なお、録画時間を超える値を指定した場合、最後のフレームが返却されます。 77 | 78 | * `seconds` 録画の何フレーム目を取得するか時間(秒)で指定 79 | 80 | ## void RecShare.SetFrameInterval(int frameInterval) 81 | 82 | 録画する間隔を指定します。 83 | デフォルトは`1`(毎フレーム録画)です。 84 | 85 | * `frameInterval` 録画する間隔(フレーム数) 86 | 87 | ## void RecShare.SetFirstImage(Texture2D tex2d, Vector2 imageSize, float displayTime[, Color bgColor]) 88 | 89 | 動画の最初に差し込む画像を`Texture2D`で設定します。 90 | 録画開始前に実行する必要があります。 91 | 92 | * `tex2d` 差し込む画像 93 | * `imageSize` 画像のサイズ 94 | * `displayTime` 画像を表示する時間(秒) 95 | * `bgColor` 背景色(デフォルト:`Color.black`) 96 | 97 | 98 | > 指定するTexture2Dは、読み取り可能(`Read / Write Enabled`)である必要があります 99 | 100 | ## void RecShare.SetFirstImage(string imageName, Vector2 imageSize, float displayTime[, Color bgColor]) 101 | 102 | 動画の最初に差し込む画像を画像名で設定します。 103 | 録画開始前に実行する必要があります。 104 | 105 | * `imageName` 差し込む画像の画像名 106 | * `imageSize` 画像のサイズ 107 | * `displayTime` 画像を表示する時間(秒) 108 | * `bgColor` 背景色(デフォルト:`Color.black`) 109 | 110 | > 画像は`Assets/RecShare/Editor/Images`、または`Assets/RecShare/Editor/Images.xcassets`に配置します。 111 | `Images.xcassets`の場合、Asset Catalog形式で配置します。 112 | 配置した画像を`imageName`引数で指定します。 113 | 114 | ## void RecShare.SetLastImage(Texture2D tex2d, Vector2 imageSize, float displayTime[, Color bgColor]) 115 | 116 | 動画の最後に差し込む画像を`Texture2D`で設定します。 117 | 録画開始前に実行する必要があります。 118 | 119 | * `tex2d` 差し込む画像 120 | * `imageSize` 画像のサイズ 121 | * `displayTime` 画像を表示する時間(秒) 122 | * `bgColor` 背景色(デフォルト:`Color.black`) 123 | 124 | 125 | > 指定するTexture2Dは、読み取り可能(`Read / Write Enabled`)である必要があります 126 | 127 | ## void RecShare.SetLastImage(string imageName, Vector2 imageSize, float displayTime[, Color bgColor]) 128 | 129 | 動画の最後に差し込む画像を画像名で設定します。 130 | 録画開始前に実行する必要があります。 131 | 132 | * `imageName` 差し込む画像の画像名 133 | * `imageSize` 画像のサイズ 134 | * `displayTime` 画像を表示する時間(秒) 135 | * `bgColor` 背景色(デフォルト:`Color.black`) 136 | 137 | > 画像は`Assets/RecShare/Editor/Images`、または`Assets/RecShare/Editor/Images.xcassets`に配置します。 138 | `Images.xcassets`の場合、Asset Catalog形式で配置します。 139 | 配置した画像を`imageName`引数で指定します。 140 | 141 | ## void RecShare.SetOverlayImage(Texture2D tex2d, Vector2 imageSize, RecShare.Alignment alignment) 142 | 143 | 動画に重ねる画像をTexture2Dで指定します。 144 | 録画開始前に実行する必要があります。 145 | `SetOverlayImage`を使用した場合、録画中のCPU消費が増加します。 146 | 147 | * `tex2d` 重ねる画像 148 | * `imageSize` 画像のサイズ 149 | * `alignment ` 画像を表示する位置 150 | 151 | > 指定するTexture2Dは、読み取り可能(`Read / Write Enabled`)である必要があります 152 | 153 | ## void RecShare.SetOverlayImage(string imageName, Vector2 imageSize, RecShare.Alignment alignment) 154 | 155 | 動画に重ねる画像を画像名で指定します。 156 | 録画開始前に実行する必要があります。 157 | `SetOverlayImage`を使用した場合、録画中のCPU消費が増加します。 158 | 159 | * `imageName` 重ねる画像の画像名 160 | * `imageSize` 画像のサイズ 161 | * `alignment ` 画像を表示する位置 162 | 163 | > 画像は`Assets/RecShare/Editor/Images`、または`Assets/RecShare/Editor/Images.xcassets`に配置します。 164 | `Images.xcassets`の場合、Asset Catalog形式で配置します。 165 | 配置した画像を`imageName`引数で指定します。 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityRecShare 2 | 3 | You can record and share your gameplay. 4 | 5 | English | [日本語](README.ja.md) 6 | 7 | 8 | # Supported 9 | * >= Unity 5.3 10 | * >= iOS 8 11 | 12 | (iOS Only, Without sound) 13 | 14 | 15 | # Usage 16 | * Import `RecShare.unitypackage` 17 | * If the sample is necessary, import additional `RecShareSample.unitypackage` 18 | 19 | 20 | # API 21 | 22 | ## void RecShare.Initialize() 23 | 24 | Perform the initial processing. You need call before start recording. 25 | 26 | 27 | ## void RecShare.StartRecording() 28 | 29 | Start recording. 30 | 31 | ## void RecShare.StopRecording(Action completion = null) 32 | 33 | Stop recording. 34 | 35 | * `completion` Called at record completion 36 | 37 | ## void RecShare.PauseRecording 38 | 39 | Pause recording. 40 | 41 | ## void RecShare.ResumeRecording 42 | 43 | Resume Recording. 44 | 45 | ## bool RecShare.IsRecording 46 | 47 | if during recording, return the `true'. 48 | 49 | ## bool RecShare.IsPaused 50 | 51 | if during pausing, return the `true'. 52 | 53 | ## void RecShare.ShowSharingModal(string text = "") 54 | 55 | Show sharing sheet. 56 | 57 | * `text` sharing text 58 | 59 | ## void RecShare.ShowVideoPlayer 60 | 61 | Show video player. 62 | 63 | ## string RecShare.GetVideoFilePath 64 | 65 | Return the recorded video file path. 66 | 67 | ## float RecShare.GetVideoDuration 68 | 69 | Return the recorded video duration. 70 | 71 | ## Texture2D RecShare.GetScreenShot(float seconds) 72 | 73 | Return the screen shot image. 74 | 75 | * `seconds` Time to take screen shot.(sec)1 76 | 77 | ## void RecShare.SetFrameInterval(int frameInterval) 78 | 79 | Set the recording interval. 80 | Default is `1' (recording every frame) 81 | 82 | * `frameInterval` recording interval (frame) 83 | 84 | ## void RecShare.SetFirstImage(Texture2D tex2d, Vector2 imageSize, float displayTime[, Color bgColor]) 85 | 86 | Set the video of the first to insert the image in `Texture2D`. 87 | You need to run before the start of recording. 88 | 89 | * `tex2d` Insert image 90 | * `imageSize` Image size 91 | * `displayTime` Display time(sec) 92 | * `bgColor` Background color(default:`Color.black`) 93 | 94 | > Texture2D must be readable.(`Read / Write Enabled`) 95 | 96 | ## void RecShare.SetFirstImage(string imageName, Vector2 imageSize, float displayTime[, Color bgColor]) 97 | 98 | Set the video of the first to lat the image in `Texture2D`. 99 | You need to run before the start of recording. 100 | 101 | * `imageName` Image name 102 | * `imageSize` Image size 103 | * `displayTime` Display time(sec) 104 | * `bgColor` Background color(default:`Color.black`) 105 | 106 | > You can set image to `Assets/RecShare/Editor/Images` or `Assets/RecShare/Editor/Images.xcassets`. 107 | if set to `Images.xcassets`, you need to Asset Catalog format. 108 | 109 | ## void RecShare.SetLastImage(Texture2D tex2d, Vector2 imageSize, float displayTime[, Color bgColor]) 110 | 111 | Set the video of the last to insert the image in `Texture2D`. 112 | You need to run before the start of recording. 113 | 114 | * `tex2d` Insert image 115 | * `imageSize` Image size 116 | * `displayTime` Display time(sec) 117 | * `bgColor` Background color(default:`Color.black`) 118 | 119 | > Texture2D must be readable.(`Read / Write Enabled`) 120 | 121 | ## void RecShare.SetLastImage(string imageName, Vector2 imageSize, float displayTime[, Color bgColor]) 122 | 123 | Set the video of the last to lat the image in `Texture2D`. 124 | You need to run before the start of recording. 125 | 126 | * `imageName` Image name 127 | * `imageSize` Image size 128 | * `displayTime` Display time(sec) 129 | * `bgColor` Background color(default:`Color.black`) 130 | 131 | > You can set image to `Assets/RecShare/Editor/Images` or `Assets/RecShare/Editor/Images.xcassets`. 132 | if set to `Images.xcassets`, you need to Asset Catalog format. 133 | 134 | ## void RecShare.SetOverlayImage(Texture2D tex2d, Vector2 imageSize, RecShare.Alignment alignment) 135 | 136 | Set the image superimposed on the video in Texture2D. 137 | You need to run before the start of recording. 138 | If you use the `SetOverlayImage`, CPU consumption during the recording will increase. 139 | 140 | * `tex2d` Overlay image 141 | * `imageSize` Image size 142 | * `alignment ` Image alignment 143 | 144 | > Texture2D must be readable.(`Read / Write Enabled`) 145 | 146 | ## void RecShare.SetOverlayImage(string imageName, Vector2 imageSize, RecShare.Alignment alignment) 147 | 148 | Set the image superimposed on the video in image name. 149 | You need to run before the start of recording. 150 | If you use the `SetOverlayImage`, CPU consumption during the recording will increase. 151 | 152 | * `imageName` Image name 153 | * `imageSize` Image size 154 | * `alignment ` Image alignment 155 | 156 | > You can set image to `Assets/RecShare/Editor/Images` or `Assets/RecShare/Editor/Images.xcassets`. 157 | if set to `Images.xcassets`, you need to Asset Catalog format. 158 | 159 | -------------------------------------------------------------------------------- /RecShare.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare.unitypackage -------------------------------------------------------------------------------- /RecShare/Assets/RecShare.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1099cac0c4204c468149e5366d29be5 3 | folderAsset: yes 4 | timeCreated: 1465999597 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f9ebc180268794a508487ae82cff0c91 3 | folderAsset: yes 4 | timeCreated: 1465999597 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed719f5fa8c1043a1bdead6b32b95a8e 3 | folderAsset: yes 4 | timeCreated: 1471792039 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5687d988bed24fa4acfcb06983d71f8 3 | folderAsset: yes 4 | timeCreated: 1465658419 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/README.txt: -------------------------------------------------------------------------------- 1 | Put the "Asset calalog" in this directory. 2 | 3 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/README.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 26084e8a834e24b10a6e438a88546523 3 | timeCreated: 1472273920 4 | licenseType: Pro 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afa2eae044207424494f2aebf1921254 3 | folderAsset: yes 4 | timeCreated: 1465400471 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "filename" : "twitter_icon60.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "filename" : "twitter_icon120.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "filename" : "twitter_icon180.png", 16 | "scale" : "3x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "filename" : "twitter_icon76.png", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "filename" : "twitter_icon152.png", 26 | "scale" : "2x" 27 | } 28 | ], 29 | "info" : { 30 | "version" : 1, 31 | "author" : "xcode" 32 | } 33 | } -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/Contents.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3864f09c5d4a44a3591aab723ad72043 3 | timeCreated: 1465400474 4 | licenseType: Pro 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon120.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon120.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d108ce8b198f04dccaa270966efc07b2 3 | timeCreated: 1465400472 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon152.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon152.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62a9832b1186e4c1fba93b3d9a37140f 3 | timeCreated: 1465400472 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon180.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon180.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a65be773110eb4805ac465222c56a3a0 3 | timeCreated: 1465400473 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon60.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon60.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 317a2328ee88949e8a05dcb7c0fdd154 3 | timeCreated: 1465400472 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon76.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/twitter_icon.imageset/twitter_icon76.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd1d6b534a5d14fd29a660a8dd840724 3 | timeCreated: 1465400472 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06b968a78fa66403998c790bb48cd753 3 | folderAsset: yes 4 | timeCreated: 1465522007 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "video_icon15.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "video_icon30.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "video_icon45.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/Contents.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 281ced7154c1e40ad91aae41531f36f4 3 | timeCreated: 1465522008 4 | licenseType: Pro 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon15.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon15.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 678bdde4c871843d696978675383a057 3 | timeCreated: 1465522008 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon30.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon30.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06e22012daa474ea293ba882d28959a8 3 | timeCreated: 1465522008 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon45.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images.xcassets/video_icon.imageset/video_icon45.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 481073cc4351f4ad7beebb05f05681a5 3 | timeCreated: 1465522008 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/README.txt: -------------------------------------------------------------------------------- 1 | Put the image files in this directory. 2 | 3 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/README.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9783c8d28fe8744aa95d0c3a4c3aa829 3 | timeCreated: 1472273920 4 | licenseType: Pro 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images/logo.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/logo.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b68f6652eb81542a7b37318af55055b5 3 | timeCreated: 1472228807 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images/logo@2x.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/logo@2x.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06d03017e763447dcbe76552efec1f08 3 | timeCreated: 1472228799 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images/logo@3x.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/logo@3x.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 132fd65767d8f44d285f29d6356f66df 3 | timeCreated: 1472228799 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images/title.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/title.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ea6d7ec3a49974e4194723ae9573d992 3 | timeCreated: 1471795210 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/title@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images/title@2x.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/title@2x.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 37325ff9a7d7d4f228aa6c42bafd1098 3 | timeCreated: 1472227915 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/title@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Editor/Images/title@3x.png -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/Images/title@3x.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41614a1952e10424c9f64d61abab66ec 3 | timeCreated: 1472227920 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | serializedVersion: 2 53 | sprites: [] 54 | outline: [] 55 | spritePackingTag: 56 | userData: 57 | assetBundleName: 58 | assetBundleVariant: 59 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/RecSharePostProcessBuild.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_IOS 2 | using UnityEditor; 3 | using UnityEditor.Callbacks; 4 | using UnityEditor.iOS.Xcode; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | 9 | namespace RecShare { 10 | public class RecSharePostProcessBuild { 11 | 12 | [PostProcessBuild] 13 | public static void OnPostProcessBuild(BuildTarget buildTarget, string path) { 14 | 15 | copyAssetCatalogFiles("./Assets/RecShare/Editor/Images.xcassets", 16 | Path.Combine(path, "Unity-iPhone/Images.xcassets")); 17 | 18 | 19 | string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; 20 | 21 | PBXProject proj = new PBXProject(); 22 | proj.ReadFromString(File.ReadAllText(projPath)); 23 | string target = proj.TargetGuidByName("Unity-iPhone"); 24 | 25 | var toImageDir = Path.Combine(path, "Libraries/RecShare/Images"); 26 | if (!Directory.Exists(toImageDir)) { 27 | Directory.CreateDirectory(toImageDir); 28 | } 29 | 30 | var dirInfo = new DirectoryInfo("./Assets/RecShare/Editor/Images"); 31 | foreach (FileInfo fileInfo in dirInfo.GetFiles()) { 32 | if (fileInfo.Name.StartsWith(".") || fileInfo.Name.EndsWith(".meta") || fileInfo.Name.EndsWith(".txt")) { 33 | continue; 34 | } 35 | copyFileOrDirectory(fileInfo.FullName, Path.Combine(toImageDir, fileInfo.Name)); 36 | 37 | var f = Path.Combine("Libraries/RecShare/Images", fileInfo.Name); 38 | proj.AddFileToBuild(target, proj.AddFile(f, f, PBXSourceTree.Source)); 39 | } 40 | 41 | File.WriteAllText(projPath, proj.WriteToString()); 42 | } 43 | 44 | private static void copyAssetCatalogFiles(string srcPath, string dstPath) { 45 | foreach (var srcDir in Directory.GetDirectories(srcPath)) { 46 | var pathArr = srcDir.Split(Path.DirectorySeparatorChar); 47 | var dirName = pathArr.Last(); 48 | var dstDir = Path.Combine(dstPath, dirName); 49 | if (!Directory.Exists(dstDir)) { 50 | Directory.CreateDirectory(dstDir); 51 | } 52 | foreach (var file in Directory.GetFiles(srcDir)) { 53 | var fileName = Path.GetFileName(file); 54 | if (fileName.StartsWith(".") || fileName.EndsWith(".meta") || fileName.EndsWith(".txt")) { 55 | continue; 56 | } 57 | var filePath = Path.Combine(dstDir, fileName); 58 | if (File.Exists(filePath)) { 59 | File.Delete(filePath); 60 | } 61 | File.Copy(file, filePath); 62 | } 63 | } 64 | } 65 | 66 | private static void copyFileOrDirectory(string fromPath, string toPath) { 67 | if (File.Exists(toPath)) { 68 | File.Delete(toPath); 69 | 70 | } else if (Directory.Exists(toPath)) { 71 | Directory.Delete(toPath, true); 72 | } 73 | 74 | if (File.Exists(fromPath)) { 75 | File.Copy(fromPath, toPath); 76 | 77 | } else if (Directory.Exists(fromPath)) { 78 | Directory.CreateDirectory(toPath); 79 | 80 | foreach (string name in Directory.GetFiles(fromPath)) { 81 | if (name.StartsWith(".") || name.EndsWith(".meta") || name.EndsWith(".txt")) { 82 | continue; 83 | } 84 | FileInfo fInfo = new FileInfo(name); 85 | 86 | copyFileOrDirectory(fInfo.FullName, Path.Combine(toPath, fInfo.Name)); 87 | } 88 | foreach (string name in Directory.GetDirectories(fromPath)) { 89 | if (name.StartsWith(".")) { 90 | continue; 91 | } 92 | DirectoryInfo dInfo = new DirectoryInfo(name); 93 | 94 | copyFileOrDirectory(dInfo.FullName, Path.Combine(toPath, dInfo.Name)); 95 | } 96 | } 97 | } 98 | } 99 | } 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Editor/RecSharePostProcessBuild.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f87312b2dfbca4716ba3e2c26adcce6b 3 | timeCreated: 1470674128 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a01ae3c5aa4ad4625bc52897179f634c 3 | folderAsset: yes 4 | timeCreated: 1465999597 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e52bd6568c42e44a78fc816efc5a235f 3 | folderAsset: yes 4 | timeCreated: 1460208140 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf014679f71974f95a71a00a9390c22d 3 | folderAsset: yes 4 | timeCreated: 1462519619 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareAppController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecShareAppController.h 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/06. 6 | // 7 | // 8 | 9 | #import "UnityAppController.h" 10 | #import "RecShareManager.h" 11 | 12 | @interface RecShareAppController : UnityAppController 13 | 14 | - (void)shouldAttachRenderDelegate; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareAppController.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 26037d856b8e34e40980a167927e7009 3 | timeCreated: 1462519635 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 1 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | userData: 19 | assetBundleName: 20 | assetBundleVariant: 21 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareAppController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecShareAppController.m 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/06. 6 | // 7 | // 8 | 9 | #import "RecShareAppController.h" 10 | 11 | @implementation RecShareAppController 12 | 13 | - (void)shouldAttachRenderDelegate { 14 | self.renderDelegate = [RecShareManager new]; 15 | } 16 | 17 | 18 | @end 19 | 20 | IMPL_APP_CONTROLLER_SUBCLASS(RecShareAppController) 21 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareAppController.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1f89bf90620e4bfcab132fb42045cfb 3 | timeCreated: 1462519635 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | tvOS: 22 | enabled: 1 23 | settings: {} 24 | userData: 25 | assetBundleName: 26 | assetBundleVariant: 27 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecShareManager.h 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/06. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import "UnityAppController.h" 16 | #import "DisplayManager.h" 17 | #import "VideoCreator.h" 18 | #import "TwitterActivity.h" 19 | 20 | 21 | @interface RecShareManager : RenderPluginDelegate 22 | 23 | - (void)initialize; 24 | - (void)startRecoding; 25 | - (void)stopRecording:(void (^)(bool ret))completion; 26 | - (void)pauseRecording; 27 | - (void)resumeRecording; 28 | - (BOOL)isRecording; 29 | - (BOOL)isPaused; 30 | - (void)showSharingModal:(NSString *)tweetText; 31 | - (void)showVideoPlayer; 32 | - (NSString *)getVideoFilePath; 33 | - (float)getVideoDuration; 34 | - (NSData *)getScreenShotImage:(Float64)seconds; 35 | - (void)setFrameInterval:(int)frameInterval; 36 | 37 | - (void)setFirstImage:(UIImage *)image imageSize:(CGSize)imageSize bgColor:(UIColor *)bgColor frames:(int)frames; 38 | - (void)setLastImage:(UIImage *)image imageSize:(CGSize)imageSize bgColor:(UIColor *)bgColor frames:(int)frames; 39 | - (void)setOverlayImage:(UIImage *)image imageSize:(CGSize)imageSize alignment:(VideoCreatorImageAlignment)alignment; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareManager.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2eaed97e746094462a837be6c5b63504 3 | timeCreated: 1462519635 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 1 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | userData: 19 | assetBundleName: 20 | assetBundleVariant: 21 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareManager.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RecShareManager.m 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/06. 6 | // 7 | // 8 | 9 | #import "RecShareManager.h" 10 | #import "CVTextureCache.h" 11 | 12 | #define TMP_RECORDING_FILE_NAME @"RecShare_Recording.mp4" 13 | #define TMP_COMPLETE_FILE_NAME @"RecShare_Complete.mp4" 14 | 15 | 16 | @implementation RecShareManager { 17 | AVAssetWriter *_videoWriter; 18 | AVAssetWriterInput *_videoInput; 19 | AVAssetWriterInput *_audioInput; 20 | AVAssetWriterInputPixelBufferAdaptor *_adaptor; 21 | BOOL _recording; 22 | BOOL _recorded; 23 | BOOL _paused; 24 | int _frameInterval; 25 | int _tmpInterval; 26 | VideoCreator *_videoCreator; 27 | 28 | CVPixelBufferRef _firstImagePixelbuffer; 29 | int _firstImageFrames; 30 | CVPixelBufferRef _lastImagePixelbuffer; 31 | int _lastImageFrames; 32 | 33 | CIImage *_overlayImage; 34 | CGRect _overlayFrame; 35 | } 36 | 37 | - (void)initialize { 38 | @synchronized(self) { 39 | if (_videoCreator) { 40 | return; 41 | } 42 | 43 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 44 | CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)mainDisplaySurface->cvPixelBuffer; 45 | int bufferW = (int)CVPixelBufferGetWidth(pixelBuffer); 46 | int bufferH = (int)CVPixelBufferGetHeight(pixelBuffer); 47 | 48 | if (_frameInterval <= 0) { 49 | _frameInterval = 1; 50 | } 51 | 52 | NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:TMP_RECORDING_FILE_NAME]; 53 | int fps = UnityGetTargetFPS() / _frameInterval; 54 | _videoCreator = [[VideoCreator alloc] initWithOptions:filePath fps:fps]; 55 | 56 | [_videoCreator initWriter:bufferW height:bufferH]; 57 | }); 58 | } 59 | } 60 | 61 | - (void)startRecoding { 62 | @synchronized(self) { 63 | NSLog(@"[RecShareManager] startRecoding"); 64 | 65 | if (_recording) { 66 | NSLog(@"[RecShareManager] already started."); 67 | return; 68 | } 69 | 70 | if (!_videoCreator) { 71 | NSLog(@"[RecShareManager] did not initialized"); 72 | return; 73 | } 74 | 75 | if (_firstImagePixelbuffer) { 76 | [_videoCreator appendPixelBuffer:_firstImagePixelbuffer frameCounter:_firstImageFrames]; 77 | } 78 | 79 | _recording = YES; 80 | _recorded = NO; 81 | _paused = NO; 82 | _tmpInterval = 0; 83 | } 84 | } 85 | 86 | - (void)stopRecording:(void (^)(bool ret))completion { 87 | NSLog(@"[RecShareManager] stopRecording"); 88 | 89 | if (!_videoCreator) { 90 | return; 91 | } 92 | 93 | _recording = NO; 94 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 95 | if (_lastImagePixelbuffer) { 96 | if (_lastImageFrames > 1) { 97 | [_videoCreator appendPixelBuffer:_lastImagePixelbuffer frameCounter:_lastImageFrames - 1]; 98 | } 99 | [_videoCreator appendPixelBuffer:_lastImagePixelbuffer]; 100 | } 101 | 102 | [_videoCreator finalizeWriter:^{ 103 | _paused = NO; 104 | _recorded = YES; 105 | _videoCreator = nil; 106 | 107 | if ([[NSFileManager defaultManager] fileExistsAtPath:[self getVideoFilePath]]) { 108 | [[NSFileManager defaultManager] removeItemAtPath:[self getVideoFilePath] error:nil]; 109 | } 110 | [[NSFileManager defaultManager] moveItemAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:TMP_RECORDING_FILE_NAME] 111 | toPath:[self getVideoFilePath] 112 | error:nil]; 113 | [self initialize]; 114 | 115 | dispatch_async(dispatch_get_main_queue(), ^{ 116 | completion(true); 117 | }); 118 | }]; 119 | }); 120 | } 121 | 122 | - (void)pauseRecording { 123 | NSLog(@"[RecShareManager] pauseRecording"); 124 | 125 | if (!_recording) { 126 | return; 127 | } 128 | 129 | _paused = YES; 130 | } 131 | 132 | - (void)resumeRecording { 133 | NSLog(@"[RecShareManager] resumeRecording"); 134 | 135 | if (!_recording) { 136 | return; 137 | } 138 | 139 | _paused = NO; 140 | } 141 | 142 | - (BOOL)isRecording { 143 | return _recording; 144 | } 145 | 146 | - (BOOL)isPaused { 147 | return _paused; 148 | } 149 | 150 | - (void)showSharingModal:(NSString *)tweetText { 151 | NSLog(@"[RecShareManager] showSharingModal"); 152 | 153 | if (_recording || !_recorded) { 154 | return; 155 | } 156 | 157 | NSURL *videoFileUrl = [NSURL fileURLWithPath:[self getVideoFilePath]]; 158 | 159 | NSArray* actItems = @[tweetText, videoFileUrl]; 160 | UIActivity *twitterActivity = [TwitterActivity new]; 161 | NSArray *activities = @[twitterActivity]; 162 | 163 | UIActivityViewController *activityViewController = 164 | [[UIActivityViewController alloc] initWithActivityItems:actItems applicationActivities:activities]; 165 | activityViewController.popoverPresentationController.sourceView = UnityGetGLViewController().view; 166 | 167 | [UnityGetGLViewController() presentViewController:activityViewController animated:YES completion:nil]; 168 | } 169 | 170 | - (NSString *)getVideoFilePath { 171 | return [NSTemporaryDirectory() stringByAppendingPathComponent:TMP_COMPLETE_FILE_NAME]; 172 | } 173 | 174 | - (float)getVideoDuration { 175 | if (_recording || !_recorded) { 176 | return 0; 177 | } 178 | 179 | NSString *filePath = [self getVideoFilePath]; 180 | if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) { 181 | return 0.0f; 182 | } 183 | NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; 184 | AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:fileUrl options:nil]; 185 | Float64 duration = CMTimeGetSeconds([asset duration]); 186 | 187 | return (float)duration; 188 | } 189 | 190 | - (void)showVideoPlayer { 191 | NSLog(@"[RecShareManager] showVideoPlayer"); 192 | 193 | NSURL *fileUrl = [NSURL fileURLWithPath:[self getVideoFilePath]]; 194 | AVPlayerViewController *viewController = [AVPlayerViewController new]; 195 | viewController.player = [AVPlayer playerWithURL:fileUrl]; 196 | [UnityGetGLViewController() presentViewController:viewController animated:YES completion:nil]; 197 | } 198 | 199 | - (NSData *)getScreenShotImage:(Float64)seconds { 200 | NSURL *fileUrl = [NSURL fileURLWithPath:[self getVideoFilePath]]; 201 | AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:fileUrl options:nil]; 202 | AVAssetImageGenerator *imageGen = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 203 | CGImageRef screenShot = [imageGen copyCGImageAtTime:CMTimeMakeWithSeconds(seconds, NSEC_PER_SEC) actualTime:nil error:nil]; 204 | 205 | return UIImagePNGRepresentation([UIImage imageWithCGImage:screenShot]); 206 | } 207 | 208 | - (void)setFrameInterval:(int)frameInterval { 209 | _frameInterval = frameInterval; 210 | } 211 | 212 | - (void)setFirstImage:(UIImage *)image imageSize:(CGSize)imageSize bgColor:(UIColor *)bgColor frames:(int)frames { 213 | CGRect center = [self getCenterRectForPixelBuffer:image size:imageSize]; 214 | _firstImagePixelbuffer = [VideoCreator getPixelBufferFromCGImage:image.CGImage imageRect:center bgColor:bgColor]; 215 | _firstImageFrames = frames; 216 | } 217 | 218 | - (void)setLastImage:(UIImage *)image imageSize:(CGSize)imageSize bgColor:(UIColor *)bgColor frames:(int)frames { 219 | CGRect center = [self getCenterRectForPixelBuffer:image size:imageSize]; 220 | _lastImagePixelbuffer = [VideoCreator getPixelBufferFromCGImage:image.CGImage imageRect:center bgColor:bgColor]; 221 | _lastImageFrames = frames; 222 | } 223 | 224 | - (void)setOverlayImage:(UIImage *)image imageSize:(CGSize)imageSize alignment:(VideoCreatorImageAlignment)alignment { 225 | CGRect center = [self getCenterRectForPixelBuffer:image size:imageSize]; 226 | CGSize screenSize = [UIScreen mainScreen].nativeBounds.size; 227 | 228 | CVPixelBufferRef pixelBuffer = [VideoCreator getPixelBufferFromCGImage:image.CGImage imageRect:center bgColor:nil]; 229 | _overlayImage = [CIImage imageWithCVPixelBuffer:pixelBuffer]; 230 | 231 | CGFloat offsetY = screenSize.height / 2 - center.size.height / 2; 232 | CGFloat offsetX = screenSize.width / 2 - center.size.width / 2; 233 | 234 | switch (alignment) { 235 | case VideoCreatorImageAlignmentTopCenter: 236 | _overlayFrame = CGRectMake(0, -offsetY, screenSize.width, screenSize.height); 237 | break; 238 | 239 | case VideoCreatorImageAlignmentTopLeft: 240 | _overlayFrame = CGRectMake(-offsetX, -offsetY, screenSize.width, screenSize.height); 241 | break; 242 | 243 | case VideoCreatorImageAlignmentTopRight: 244 | _overlayFrame = CGRectMake(offsetX, -offsetY, screenSize.width, screenSize.height); 245 | break; 246 | 247 | case VideoCreatorImageAlignmentBottomCenter: 248 | _overlayFrame = CGRectMake(0, offsetY, screenSize.width, screenSize.height); 249 | break; 250 | 251 | case VideoCreatorImageAlignmentBottomLeft: 252 | _overlayFrame = CGRectMake(offsetX, offsetY, screenSize.width, screenSize.height); 253 | break; 254 | 255 | case VideoCreatorImageAlignmentBottomRight: 256 | _overlayFrame = CGRectMake(-offsetX, offsetY, screenSize.width, screenSize.height); 257 | break; 258 | } 259 | } 260 | 261 | 262 | # pragma - RenderPluginDelegate 263 | 264 | - (void)onBeforeMainDisplaySurfaceRecreate:(struct RenderingSurfaceParams *)params { 265 | params->useCVTextureCache = true; 266 | } 267 | 268 | - (void)onFrameResolved { 269 | if (!_recording || _paused) { 270 | return; 271 | } 272 | 273 | if (++_tmpInterval < _frameInterval) { 274 | return; 275 | } 276 | 277 | CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)mainDisplaySurface->cvPixelBuffer; 278 | 279 | if (_overlayImage) { 280 | [_videoCreator appendPixelBuffer:pixelBuffer overlayImage:_overlayImage overlayFrame:_overlayFrame]; 281 | 282 | } else { 283 | [_videoCreator appendPixelBuffer:pixelBuffer]; 284 | } 285 | 286 | _tmpInterval = 0; 287 | } 288 | 289 | 290 | #pragma - Private Methods 291 | 292 | - (CGRect)getCenterRectForPixelBuffer:(UIImage *)image size:(CGSize)size { 293 | CGFloat screenScale = [UIScreen mainScreen].nativeScale; 294 | CGSize screenSize = [UIScreen mainScreen].nativeBounds.size; 295 | 296 | size.width *= screenScale; 297 | size.height *= screenScale; 298 | 299 | CGPoint point = CGPointMake(screenSize.width / 2 - size.width / 2, screenSize.height / 2 - size.height / 2); 300 | return CGRectMake(point.x, point.y, size.width, size.height); 301 | } 302 | 303 | 304 | @end 305 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecShareManager.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39ce1209abafc4f62bde570b2994e27d 3 | timeCreated: 1468773209 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | tvOS: 22 | enabled: 1 23 | settings: {} 24 | userData: 25 | assetBundleName: 26 | assetBundleVariant: 27 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecSharePlugin.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RecSharePlugin.mm 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/06. 6 | // 7 | // 8 | 9 | #import "RecShareManager.h" 10 | 11 | extern "C" { 12 | 13 | typedef void *_CS_RecShare_Instance; 14 | typedef void (*_CS_RecShare_Completion)(_CS_RecShare_Instance, bool); 15 | 16 | RecShareManager *__RecSharePlugin_getManager() { 17 | UnityAppController *unityAppController = (UnityAppController*)[UIApplication sharedApplication].delegate; 18 | if (unityAppController.renderDelegate && [unityAppController.renderDelegate isKindOfClass:[RecShareManager class]]) { 19 | return (RecShareManager *)unityAppController.renderDelegate; 20 | } 21 | return nil; 22 | } 23 | 24 | UIImage *__RecSharePlugin_getUIImage(Byte *bytes, int length) { 25 | NSData *data = [NSData dataWithBytes:bytes length:length]; 26 | return [UIImage imageWithData:data]; 27 | } 28 | 29 | 30 | void _RecSharePlugin_initialize() { 31 | [__RecSharePlugin_getManager() initialize]; 32 | } 33 | 34 | void _RecSharePlugin_startRecoding() { 35 | [__RecSharePlugin_getManager() startRecoding]; 36 | } 37 | 38 | void _RecSharePlugin_stopRecording(_CS_RecShare_Instance instance, _CS_RecShare_Completion completion) { 39 | [__RecSharePlugin_getManager() stopRecording:^(bool ret) { 40 | completion(instance, ret); 41 | }]; 42 | } 43 | 44 | void _RecSharePlugin_pauseRecording() { 45 | [__RecSharePlugin_getManager() pauseRecording]; 46 | } 47 | 48 | void _RecSharePlugin_resumeRecording() { 49 | [__RecSharePlugin_getManager() resumeRecording]; 50 | } 51 | 52 | bool _RecSharePlugin_isRecording() { 53 | return [__RecSharePlugin_getManager() isRecording]; 54 | } 55 | 56 | bool _RecSharePlugin_isPaused() { 57 | return [__RecSharePlugin_getManager() isPaused]; 58 | } 59 | 60 | void _RecSharePlugin_showSharingModal(const char *text) { 61 | [__RecSharePlugin_getManager() showSharingModal:[NSString stringWithUTF8String:text]]; 62 | } 63 | 64 | void _RecSharePlugin_showVideoPlayer() { 65 | [__RecSharePlugin_getManager() showVideoPlayer]; 66 | } 67 | 68 | const char *_RecSharePlugin_getVideoFilePath() { 69 | NSString *path = [__RecSharePlugin_getManager() getVideoFilePath]; 70 | const char *str = [path UTF8String]; 71 | char* retStr = (char*)malloc(strlen(str) + 1); 72 | strcpy(retStr, str); 73 | return retStr; 74 | } 75 | 76 | float _RecSharePlugin_getVideoDuration() { 77 | return [__RecSharePlugin_getManager() getVideoDuration]; 78 | } 79 | 80 | void _RecSharePlugin_getScreenShotImage(float seconds, Byte **byteArrPtr, int *size) { 81 | NSData *data = [__RecSharePlugin_getManager() getScreenShotImage:seconds]; 82 | NSUInteger len = [data length]; 83 | Byte *byteArr = (Byte*)malloc(len); 84 | memcpy(byteArr, [data bytes], len); 85 | 86 | *byteArrPtr = byteArr; 87 | *size = (int)len; 88 | } 89 | 90 | void _RecSharePlugin_setFrameInterval(int frameInterval) { 91 | [__RecSharePlugin_getManager() setFrameInterval:frameInterval]; 92 | } 93 | 94 | void _RecSharePlugin_setFirstImage_data(Byte *bytes, int length, float width, float height, float r, float g, float b, float displayTime) { 95 | UIImage *image = __RecSharePlugin_getUIImage(bytes, length); 96 | UIColor *bgColor = [UIColor colorWithRed:r green:g blue:b alpha:1.0]; 97 | int frames = roundf(displayTime * UnityGetTargetFPS()); 98 | 99 | [__RecSharePlugin_getManager() setFirstImage:image imageSize:CGSizeMake(width, height) bgColor:bgColor frames:frames]; 100 | } 101 | 102 | void _RecSharePlugin_setFirstImage_imageName(const char *imageName, float width, float height, float r, float g, float b, float displayTime) { 103 | UIImage *image = [UIImage imageNamed:[NSString stringWithUTF8String:imageName]]; 104 | UIColor *bgColor = [UIColor colorWithRed:r green:g blue:b alpha:1.0]; 105 | int frames = roundf(displayTime * UnityGetTargetFPS()); 106 | 107 | [__RecSharePlugin_getManager() setFirstImage:image imageSize:CGSizeMake(width, height) bgColor:bgColor frames:frames]; 108 | } 109 | 110 | void _RecSharePlugin_setLastImage_data(Byte *bytes, int length, float width, float height, float r, float g, float b, float displayTime) { 111 | UIImage *image = __RecSharePlugin_getUIImage(bytes, length); 112 | UIColor *bgColor = [UIColor colorWithRed:r green:g blue:b alpha:1.0]; 113 | int frames = roundf(displayTime * UnityGetTargetFPS()); 114 | 115 | [__RecSharePlugin_getManager() setLastImage:image imageSize:CGSizeMake(width, height) bgColor:bgColor frames:frames]; 116 | } 117 | 118 | void _RecSharePlugin_setLastImage_imageName(const char *imageName, float width, float height, float r, float g, float b, float displayTime) { 119 | UIImage *image = [UIImage imageNamed:[NSString stringWithUTF8String:imageName]]; 120 | UIColor *bgColor = [UIColor colorWithRed:r green:g blue:b alpha:1.0]; 121 | int frames = roundf(displayTime * UnityGetTargetFPS()); 122 | 123 | [__RecSharePlugin_getManager() setLastImage:image imageSize:CGSizeMake(width, height) bgColor:bgColor frames:frames]; 124 | } 125 | 126 | void _RecSharePlugin_setOverlayImage_data(Byte *bytes, int length, float width, float height, int alignment) { 127 | UIImage *image = __RecSharePlugin_getUIImage(bytes, length); 128 | [__RecSharePlugin_getManager() setOverlayImage:image imageSize:CGSizeMake(width, height) alignment:(VideoCreatorImageAlignment)alignment]; 129 | } 130 | 131 | void _RecSharePlugin_setOverlayImage_imageName(const char *imageName, float width, float height, int alignment) { 132 | UIImage *image = [UIImage imageNamed:[NSString stringWithUTF8String:imageName]]; 133 | [__RecSharePlugin_getManager() setOverlayImage:image imageSize:CGSizeMake(width, height) alignment:(VideoCreatorImageAlignment)alignment]; 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/RecSharePlugin.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d75f45d74fecf40de8b692103f8b5b7e 3 | timeCreated: 1462519635 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Android: 12 | enabled: 0 13 | settings: 14 | CPU: AnyCPU 15 | Any: 16 | enabled: 0 17 | settings: {} 18 | Editor: 19 | enabled: 0 20 | settings: 21 | CPU: AnyCPU 22 | DefaultValueInitialized: true 23 | OS: AnyOS 24 | Linux: 25 | enabled: 0 26 | settings: 27 | CPU: x86 28 | Linux64: 29 | enabled: 0 30 | settings: 31 | CPU: x86_64 32 | OSXIntel: 33 | enabled: 0 34 | settings: 35 | CPU: AnyCPU 36 | OSXIntel64: 37 | enabled: 0 38 | settings: 39 | CPU: AnyCPU 40 | Win: 41 | enabled: 0 42 | settings: 43 | CPU: AnyCPU 44 | Win64: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | iOS: 49 | enabled: 1 50 | settings: 51 | CompileFlags: 52 | FrameworkDependencies: Accounts;Social;AVKit;CoreImage; 53 | userData: 54 | assetBundleName: 55 | assetBundleVariant: 56 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b7d0331582c2044eaaa1116600a37b83 3 | folderAsset: yes 4 | timeCreated: 1465999597 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetPresentationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TweetPresentationController.h 3 | // LayoutTest 4 | // 5 | // Created by tkyaji on 2016/05/23. 6 | // Copyright © 2016年 tkyaji. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TweetPresentationController : UIPresentationController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetPresentationController.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: beac2a421a8fe4bd5a9891c0a7140b59 3 | timeCreated: 1473163257 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetPresentationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TweetPresentationController.m 3 | // LayoutTest 4 | // 5 | // Created by tkyaji on 2016/05/23. 6 | // Copyright © 2016年 tkyaji. All rights reserved. 7 | // 8 | 9 | #import "TweetPresentationController.h" 10 | 11 | @implementation TweetPresentationController { 12 | UIView *_overlayView; 13 | } 14 | 15 | 16 | - (void)presentationTransitionWillBegin { 17 | _overlayView = [[UIView alloc] initWithFrame:self.containerView.bounds]; 18 | _overlayView.backgroundColor = [UIColor blackColor]; 19 | _overlayView.alpha = 0.0f; 20 | UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onOverlayTapped:)]; 21 | [_overlayView addGestureRecognizer:recognizer]; 22 | [self.containerView insertSubview:_overlayView atIndex:0]; 23 | 24 | [self.presentedViewController.transitionCoordinator animateAlongsideTransition:^(id context) { 25 | _overlayView.alpha = 0.5f; 26 | } completion:nil]; 27 | 28 | } 29 | 30 | - (void)onOverlayTapped:(UITapGestureRecognizer *)recognizer { 31 | [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; 32 | } 33 | 34 | - (CGRect)frameOfPresentedViewInContainerView { 35 | if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"]) { 36 | CGSize size = CGSizeMake(400.0f, 230.0f); 37 | return CGRectMake((self.containerView.frame.size.width - size.width) / 2.0f, 38 | (self.containerView.frame.size.height - size.height) / 2.0f - 130.0f, 39 | size.width, size.height); 40 | 41 | } else { 42 | CGSize size = CGSizeMake(self.containerView.frame.size.width - 30.0f, 230.0f); 43 | return CGRectMake((self.containerView.frame.size.width - size.width) / 2.0f, 44 | (self.containerView.frame.size.height - size.height) / 2.0f - 110.0f, 45 | size.width, size.height); 46 | } 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetPresentationController.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eafcbd56414e648a3bae9b28b117ac24 3 | timeCreated: 1473163257 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TweetViewController.h 3 | // LayoutTest 4 | // 5 | // Created by tkyaji on 2016/05/24. 6 | // Copyright © 2016年 tkyaji. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "TwitterApiCaller.h" 12 | #import "TweetPresentationController.h" 13 | #import "TwitterConfig.h" 14 | 15 | 16 | @interface TweetViewController : UIViewController 17 | 18 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *postButtonBarItem; 19 | //@property (weak, nonatomic) IBOutlet UIButton *accountButton; 20 | @property (weak, nonatomic) IBOutlet UILabel *accountArrow; 21 | @property (weak, nonatomic) IBOutlet UILabel *accountLabel; 22 | @property (weak, nonatomic) IBOutlet UIButton *accountButton; 23 | @property (weak, nonatomic) IBOutlet UITextView *textView; 24 | @property (weak, nonatomic) IBOutlet UILabel *textCount; 25 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 26 | @property (weak, nonatomic) IBOutlet UILabel *timeLabel; 27 | 28 | 29 | - (id)initWithTweet:(NSString *)tweetText videoUrl:(NSURL *)videoUrl; 30 | 31 | - (IBAction)cancelButtonClicked:(id)sender; 32 | - (IBAction)postButtonClicked:(id)sender; 33 | - (IBAction)accountButtonClicked:(id)sender; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetViewController.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53876e4ef18ef4e9ca5fc8f11e97200b 3 | timeCreated: 1473163256 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TweetViewController.m 3 | // LayoutTest 4 | // 5 | // Created by tkyaji on 2016/05/24. 6 | // Copyright © 2016年 tkyaji. All rights reserved. 7 | // 8 | 9 | #import "TweetViewController.h" 10 | 11 | #define USER_DEFAULT_KEY_SELECTED_ACCOUNT @"twitter_selected_account" 12 | 13 | @implementation TweetViewController { 14 | NSArray *_accountArr; 15 | Float64 _videoDuration; 16 | CGImageRef _screenShot; 17 | NSString *_tweetText; 18 | NSURL *_videoUrl; 19 | } 20 | 21 | - (id)init { 22 | self = [super init]; 23 | 24 | self.modalTransitionStyle = UIModalPresentationCustom; 25 | self.modalPresentationStyle = UIModalPresentationCustom; 26 | self.transitioningDelegate = self; 27 | 28 | return self; 29 | } 30 | 31 | - (id)initWithTweet:(NSString *)tweetText videoUrl:(NSURL *)videoUrl { 32 | _videoUrl = videoUrl; 33 | _tweetText = tweetText; 34 | 35 | AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil]; 36 | AVAssetImageGenerator *imageGen = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 37 | 38 | _videoDuration = CMTimeGetSeconds([asset duration]); 39 | _screenShot = [imageGen copyCGImageAtTime:CMTimeMakeWithSeconds(0.0, NSEC_PER_SEC) actualTime:nil error:nil]; 40 | 41 | return [self init]; 42 | } 43 | 44 | - (void)viewDidLoad { 45 | [super viewDidLoad]; 46 | 47 | [self.postButtonBarItem setTitleTextAttributes:@{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0f]} forState:UIControlStateNormal]; 48 | 49 | [self.textView becomeFirstResponder]; 50 | [self.textView setText:_tweetText]; 51 | [self.textView setDelegate:self]; 52 | 53 | [self setTweetTextCount]; 54 | 55 | int tm = (int)_videoDuration; 56 | [self.timeLabel setText:[NSString stringWithFormat:@"%d:%02d", (tm / 60), (tm % 60)]]; 57 | 58 | [self.imageView setImage:[UIImage imageWithCGImage:_screenShot]]; 59 | 60 | [TwitterApiCaller getTwitterAccounts:^(NSArray *accountArr, NSError *error) { 61 | if (error) { 62 | dispatch_async(dispatch_get_main_queue(), ^{ 63 | [self presentAccountAlert:error.localizedDescription message:error.localizedRecoverySuggestion completion:^(BOOL isCanceled) { 64 | [self dismissViewControllerAnimated:isCanceled completion:nil]; 65 | }]; 66 | }); 67 | 68 | } else { 69 | _accountArr = accountArr; 70 | ACAccount *account = [self selectAccount:accountArr]; 71 | 72 | dispatch_async(dispatch_get_main_queue(), ^{ 73 | [self.accountLabel setText:[NSString stringWithFormat:@"@%@", account.username]]; 74 | [self.postButtonBarItem setEnabled:YES]; 75 | if (accountArr.count > 1) { 76 | [self.accountButton setEnabled:YES]; 77 | [self.accountArrow setHidden:NO]; 78 | } 79 | }); 80 | } 81 | }]; 82 | } 83 | 84 | - (void)didReceiveMemoryWarning { 85 | [super didReceiveMemoryWarning]; 86 | // Dispose of any resources that can be recreated. 87 | } 88 | 89 | /* 90 | #pragma mark - Navigation 91 | 92 | // In a storyboard-based application, you will often want to do a little preparation before navigation 93 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 94 | // Get the new view controller using [segue destinationViewController]. 95 | // Pass the selected object to the new view controller. 96 | } 97 | */ 98 | 99 | - (void)presentAccountAlert:(NSString *)title message:(NSString *)message completion:(void (^)(BOOL isCanceled))completion { 100 | UIAlertController * alertController = 101 | [UIAlertController alertControllerWithTitle:title 102 | message:message 103 | preferredStyle:UIAlertControllerStyleAlert]; 104 | 105 | [alertController addAction:[UIAlertAction actionWithTitle:@"Settings" 106 | style:UIAlertActionStyleDefault 107 | handler:^(UIAlertAction *action) { 108 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=TWITTER"]]; 109 | completion(NO); 110 | }]]; 111 | 112 | [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" 113 | style:UIAlertActionStyleCancel 114 | handler:^(UIAlertAction *action) { 115 | completion(YES); 116 | }]]; 117 | 118 | [self presentViewController:alertController animated:YES completion:nil]; 119 | } 120 | 121 | - (ACAccount *)selectAccount:(NSArray *)accountArr { 122 | NSString *selectedAccountName = [[NSUserDefaults standardUserDefaults] stringForKey:USER_DEFAULT_KEY_SELECTED_ACCOUNT]; 123 | 124 | for (ACAccount *ac in accountArr) { 125 | if ([ac.username isEqualToString:selectedAccountName]) { 126 | return ac; 127 | } 128 | } 129 | 130 | return accountArr[0]; 131 | } 132 | 133 | - (void)presentSelectAccountAlert:(NSArray *)accountArr { 134 | UIAlertController * alertController = 135 | [UIAlertController alertControllerWithTitle:@"Select Account" 136 | message:nil 137 | preferredStyle:UIAlertControllerStyleActionSheet]; 138 | 139 | for (ACAccount *ac in accountArr) { 140 | UIAlertAction *action = [UIAlertAction actionWithTitle:[NSString stringWithFormat:@"@%@", ac.username] 141 | style:UIAlertActionStyleDefault 142 | handler:^(UIAlertAction *action) { 143 | [self.accountLabel setText:action.title]; 144 | [[NSUserDefaults standardUserDefaults] setObject:ac.username forKey:USER_DEFAULT_KEY_SELECTED_ACCOUNT]; 145 | [self.textView becomeFirstResponder]; 146 | }]; 147 | [alertController addAction:action]; 148 | } 149 | 150 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" 151 | style:UIAlertActionStyleCancel 152 | handler:^(UIAlertAction *action) { 153 | [self.textView becomeFirstResponder]; 154 | }]; 155 | [alertController addAction:cancelAction]; 156 | 157 | alertController.popoverPresentationController.sourceView = self.accountButton; 158 | alertController.popoverPresentationController.sourceRect = self.accountButton.frame; 159 | 160 | [self.textView resignFirstResponder]; 161 | 162 | [self presentViewController:alertController animated:YES completion:nil]; 163 | } 164 | 165 | - (void)setTweetTextCount { 166 | NSInteger len = TWITTER_TEXT_MAX_LENGTH - self.textView.text.length; 167 | if (len < 0) { 168 | [self.textCount setTextColor:[UIColor redColor]]; 169 | } else { 170 | [self.textCount setTextColor:[UIColor lightGrayColor]]; 171 | } 172 | [self.textCount setText:@(len).stringValue]; 173 | } 174 | 175 | 176 | #pragma mark - IBAction 177 | 178 | - (IBAction)cancelButtonClicked:(id)sender { 179 | [self dismissViewControllerAnimated:YES completion:nil]; 180 | } 181 | 182 | - (IBAction)postButtonClicked:(id)sender { 183 | ACAccount *account = [self selectAccount:_accountArr]; 184 | [TwitterApiCaller tweetWithVideo:self.textView.text videoUrl:_videoUrl account:account completion:^(NSError *error) { 185 | dispatch_async(dispatch_get_main_queue(), ^{ 186 | if (error) { 187 | NSLog(@"[RecShareManager] Tweet Error : %@", error); 188 | } 189 | }); 190 | }]; 191 | 192 | [self dismissViewControllerAnimated:YES completion:nil]; 193 | } 194 | 195 | - (IBAction)accountButtonClicked:(id)sender { 196 | [self presentSelectAccountAlert:_accountArr]; 197 | } 198 | 199 | 200 | 201 | #pragma mark - UIViewControllerTransitioningDelegate 202 | 203 | - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented 204 | presentingViewController:(UIViewController *)presenting 205 | sourceViewController:(UIViewController *)source { 206 | return [[TweetPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting]; 207 | } 208 | 209 | 210 | #pragma mark - UITextViewDelegate 211 | 212 | - (void)textViewDidChange:(UITextView *)textView { 213 | [self setTweetTextCount]; 214 | } 215 | 216 | 217 | @end 218 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetViewController.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a64f04e690683422fae603ca32f737f9 3 | timeCreated: 1473163257 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 235 | 242 | 248 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TweetViewController.xib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 155030f9995a940e1b8dfe4e05b01dbe 3 | timeCreated: 1473163256 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterActivity.h: -------------------------------------------------------------------------------- 1 | // 2 | // TwitterActivity.h 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/16. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | #import "TweetViewController.h" 12 | 13 | @interface TwitterActivity : UIActivity 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterActivity.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81a74a3bc8aa84de58b25623e0b88665 3 | timeCreated: 1473163256 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterActivity.m: -------------------------------------------------------------------------------- 1 | // 2 | // TwitterActivity.m 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/16. 6 | // 7 | // 8 | 9 | #import "TwitterActivity.h" 10 | 11 | 12 | @implementation TwitterActivity { 13 | NSString *_tweetText; 14 | NSURL *_videoFileUrl; 15 | } 16 | 17 | + (UIActivityCategory)activityCategory 18 | { 19 | return UIActivityCategoryShare; 20 | } 21 | 22 | - (NSString *)activityType { 23 | return @"com.tkyaji.TwitterActivity"; 24 | } 25 | 26 | - (NSString *)activityTitle { 27 | return @"Twitter"; 28 | } 29 | 30 | - (UIImage *)activityImage { 31 | return [UIImage imageNamed:@"twitter_icon"]; 32 | } 33 | 34 | - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { 35 | for (id activityItem in activityItems) { 36 | if (![activityItem isKindOfClass:[NSURL class]]) { 37 | continue; 38 | } 39 | 40 | NSURL *url = activityItem; 41 | if ([url.absoluteString hasSuffix:@".mp4"] || [url.absoluteString hasSuffix:@".mov"]) { 42 | AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil]; 43 | Float64 duration = CMTimeGetSeconds([asset duration]); 44 | if (duration > TWITTER_VIDEO_MAX_SEC) { 45 | return NO; 46 | } 47 | AVAssetTrack *track = [asset tracksWithMediaType:AVMediaTypeVideo][0]; 48 | if (track.nominalFrameRate > TWITTER_VIDEO_MAX_FPS) { 49 | return NO; 50 | } 51 | } 52 | } 53 | return YES; 54 | } 55 | 56 | - (void)prepareWithActivityItems:(NSArray *)activityItems { 57 | [activityItems enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 58 | if ([obj isKindOfClass:[NSString class]]) { 59 | _tweetText = obj; 60 | } else if ([obj isKindOfClass:[NSURL class]]) { 61 | _videoFileUrl = obj; 62 | } 63 | }]; 64 | } 65 | 66 | - (void)performActivity { 67 | UIViewController *viewController = [[TweetViewController alloc] initWithTweet:_tweetText videoUrl:_videoFileUrl]; 68 | [UnityGetGLViewController() presentViewController:viewController animated:YES completion:nil]; 69 | } 70 | 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterActivity.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4849d0283b9a4ef88885bc25c3c482b 3 | timeCreated: 1473163257 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterApiCaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // TwitterApiCaller.h 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/14. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface TwitterApiCaller : NSObject 14 | 15 | typedef enum { 16 | TwitterApiCallerErrorResponseEmpty, 17 | TwitterApiCallerErrorDoesNotGrantAccess, 18 | TwitterApiCallerErrorCanNotAccessAccount, 19 | TwitterApiCallerErrorNoAccount, 20 | } TwitterApiCallerErrorCode; 21 | 22 | 23 | + (void)getTwitterAccounts:(void (^)(NSArray *accountArr, NSError *error))completion; 24 | 25 | + (void)tweetWithVideo:(NSString *)tweetText videoUrl:(NSURL *)videoUrl account:(ACAccount *)account 26 | completion:(void (^)(NSError *error))completion; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterApiCaller.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 466d393b16a504573a176725bacbdba3 3 | timeCreated: 1473163256 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterApiCaller.m: -------------------------------------------------------------------------------- 1 | // 2 | // TwitterApiCaller.m 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/05/14. 6 | // 7 | // 8 | 9 | #import "TwitterApiCaller.h" 10 | 11 | #define TWITTER_UPLOAD_URL @"https://upload.twitter.com/1.1/media/upload.json" 12 | #define TWITTER_STATUSES_URL @"https://api.twitter.com/1.1/statuses/update.json" 13 | 14 | #define ErrorDomain @"com.tkyaji.twitterapicaller" 15 | 16 | 17 | @implementation TwitterApiCaller 18 | 19 | 20 | + (void)getTwitterAccounts:(void (^)(NSArray *accountArr, NSError *error))completion { 21 | ACAccountStore *accountStore = [[ACAccountStore alloc] init]; 22 | ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; 23 | [accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) { 24 | if (!granted) { 25 | NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleNameKey]; 26 | NSString *description = @"Can't access Twitter Accounts"; 27 | NSString *recoverySuggestion = [NSString stringWithFormat:@"Can't access Twitter Accounts. You can allow access to Twitter accounts to \"%@\" in Settings.", 28 | appName]; 29 | NSError *error = [NSError errorWithDomain:ErrorDomain 30 | code:TwitterApiCallerErrorCanNotAccessAccount 31 | userInfo:@{NSLocalizedDescriptionKey:description, 32 | NSLocalizedRecoverySuggestionErrorKey:recoverySuggestion}]; 33 | completion(nil, error); 34 | 35 | } else { 36 | NSArray *accountArr = [accountStore accountsWithAccountType:accountType]; 37 | if (accountArr.count == 0) { 38 | NSString *description = @"No Twitter Accounts"; 39 | NSString *recoverySuggestion = @"There are no Twitter accounts configured. You can add or create a Twitter account in Settings."; 40 | NSError *error = [NSError errorWithDomain:ErrorDomain 41 | code:TwitterApiCallerErrorCanNotAccessAccount 42 | userInfo:@{NSLocalizedDescriptionKey:description, 43 | NSLocalizedRecoverySuggestionErrorKey:recoverySuggestion}]; 44 | completion(nil, error); 45 | 46 | } else { 47 | completion(accountArr, nil); 48 | } 49 | } 50 | }]; 51 | } 52 | 53 | 54 | + (void)tweetWithVideo:(NSString *)tweetText videoUrl:(NSURL *)videoUrl account:(ACAccount *)account 55 | completion:(void (^)(NSError *error))completion { 56 | [self command_INIT:videoUrl account:account completion:^(NSString *mediaId, NSError *error) { 57 | [self command_APPEND:videoUrl account:account mediaId:mediaId completion:^(NSError *error) { 58 | [self command_FINALIZE:account mediaId:mediaId completion:^(NSError *error) { 59 | [self tweetWithMeidaId:account mediaId:mediaId tweetText:tweetText completion:^(NSError *error) { 60 | completion(error); 61 | }]; 62 | }]; 63 | }]; 64 | }]; 65 | } 66 | 67 | + (void)command_INIT:(NSURL *)videoUrl account:(ACAccount *)account completion:(void (^)(NSString *mediaId, NSError *error))completion { 68 | NSData *data = [NSData dataWithContentsOfURL:videoUrl]; 69 | 70 | NSDictionary *postParams = @{@"command": @"INIT", 71 | @"media_type": [NSString stringWithFormat:@"video/%@", videoUrl.pathExtension], 72 | @"total_bytes": [NSString stringWithFormat:@"%@", @([data length])] 73 | }; 74 | 75 | NSURL *requestUrl = [[NSURL alloc] initWithString:TWITTER_UPLOAD_URL]; 76 | 77 | [TwitterApiCaller sendPostRequest:requestUrl postParams:postParams account:account command:@"INIT" completion: 78 | ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 79 | if (error) { 80 | completion(nil, error); 81 | return; 82 | } 83 | 84 | NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 85 | NSLog(@"[TwitterApiCaller] INIT response %@",responseStr); 86 | 87 | NSError *jsonError = nil; 88 | NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError]; 89 | 90 | if (jsonError) { 91 | NSLog(@"[TwitterApiCaller] INIT error :%@",jsonError); 92 | completion(nil, jsonError); 93 | 94 | } else { 95 | NSLog(@"[TwitterApiCaller] INIT succeed %@", jsonDict); 96 | completion(jsonDict[@"media_id_string"], nil); 97 | } 98 | }]; 99 | } 100 | 101 | + (void)command_APPEND:(NSURL *)videoUrl account:(ACAccount *)account mediaId:(NSString *)mediaId completion:(void(^)(NSError *error))completion { 102 | NSData *data = [NSData dataWithContentsOfURL:videoUrl]; 103 | NSArray *separatedDataArr = [TwitterApiCaller separateData:data maxLength:5242880]; // 5MB 104 | 105 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 106 | dispatch_group_t group = dispatch_group_create(); 107 | 108 | [separatedDataArr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 109 | dispatch_group_async(group,queue, ^{ 110 | NSData *separatedData = obj; 111 | NSURL *requestUrl = [[NSURL alloc] initWithString:TWITTER_UPLOAD_URL]; 112 | NSDictionary *postParams = @{@"command": @"APPEND", 113 | @"media_id": mediaId, 114 | @"media_data": [separatedData base64Encoding], 115 | @"segment_index": [NSString stringWithFormat:@"%d", (int)idx], 116 | }; 117 | 118 | [TwitterApiCaller sendPostRequest:requestUrl postParams:postParams account:account command:@"APPEND" completion: 119 | ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 120 | completion(error); 121 | }]; 122 | }); 123 | }]; 124 | 125 | dispatch_group_wait(group,DISPATCH_TIME_FOREVER); 126 | } 127 | 128 | + (void)command_FINALIZE:(ACAccount *)account mediaId:(NSString *)mediaId completion:(void(^)(NSError *))completion { 129 | NSDictionary *postParams = @{@"command": @"FINALIZE", 130 | @"media_id": mediaId, 131 | }; 132 | 133 | NSURL *requestUrl = [[NSURL alloc] initWithString:TWITTER_UPLOAD_URL]; 134 | 135 | [TwitterApiCaller sendPostRequest:requestUrl postParams:postParams account:account command:@"FINALIZE" completion: 136 | ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 137 | completion(error); 138 | }]; 139 | } 140 | 141 | + (void)tweetWithMeidaId:(ACAccount *)account mediaId:(NSString *)mediaId tweetText:(NSString *)tweetText completion:(void(^)(NSError *error))completion { 142 | NSDictionary *postParams = @{@"media_ids": mediaId, 143 | @"status": tweetText, 144 | }; 145 | 146 | NSURL *requestUrl = [[NSURL alloc] initWithString:TWITTER_STATUSES_URL]; 147 | 148 | [TwitterApiCaller sendPostRequest:requestUrl postParams:postParams account:account command:@"Tweet" completion: 149 | ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 150 | completion(error); 151 | }]; 152 | 153 | } 154 | 155 | + (void)sendPostRequest:(NSURL *)requestUrl postParams:(NSDictionary *)postParams 156 | account:(ACAccount *)account command:(NSString *)command 157 | completion:(void (^)(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error))completion { 158 | SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter 159 | requestMethod:SLRequestMethodPOST 160 | URL:requestUrl parameters:postParams]; 161 | postRequest.account = account; 162 | 163 | NSLog(@"[TwitterApiCaller] %@ request-url:%@", command, requestUrl); 164 | NSLog(@"[TwitterApiCaller] %@ request-params:%@", command, postParams); 165 | 166 | [postRequest performRequestWithHandler: 167 | ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 168 | NSLog(@"[TwitterApiCaller] %@ response-content:%@", command, responseData); 169 | NSLog(@"[TwitterApiCaller] %@ response-http:%@", command, urlResponse); 170 | 171 | if (error || !responseData) { 172 | if (!error) { 173 | NSString *description = [NSString stringWithFormat:@"%@ command error. response data is empty.", command]; 174 | error = [NSError errorWithDomain:ErrorDomain 175 | code:TwitterApiCallerErrorResponseEmpty 176 | userInfo:@{NSLocalizedDescriptionKey: description}]; 177 | } 178 | } 179 | NSLog(@"[TwitterApiCaller] %@ error:%@", command, error); 180 | 181 | completion(responseData, urlResponse, error); 182 | }]; 183 | } 184 | 185 | + (NSArray *)separateData:(NSData*)data maxLength:(NSInteger)maxLength { 186 | NSMutableArray *dataArr = [NSMutableArray new]; 187 | 188 | NSInteger dataLength = data.length; 189 | 190 | if (dataLength <= maxLength) { 191 | [dataArr addObject:data]; 192 | 193 | } else { 194 | NSRange range = NSMakeRange(0, maxLength); 195 | while (range.location <= dataLength) { 196 | [dataArr addObject:[data subdataWithRange:range]]; 197 | 198 | range.location = range.location + maxLength; 199 | range.length = MIN(maxLength, dataLength - range.location); 200 | } 201 | } 202 | 203 | return dataArr; 204 | } 205 | 206 | @end 207 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterApiCaller.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1b6ad81db7624b009faa639cc938792 3 | timeCreated: 1473163257 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // TwitterConfig.h 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/06/10. 6 | // 7 | // 8 | 9 | #ifndef TwitterConfig_h 10 | #define TwitterConfig_h 11 | 12 | #define TWITTER_TEXT_MAX_LENGTH 140 13 | #define TWITTER_VIDEO_MAX_SEC 140 14 | #define TWITTER_VIDEO_MAX_FPS 40 15 | 16 | #endif /* TwitterConfig_h */ 17 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/Twitter/TwitterConfig.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 85f7d06d2e3c64faf9c92ef95c295584 3 | timeCreated: 1473163256 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/VideoCreator.h: -------------------------------------------------------------------------------- 1 | // 2 | // VideoCreator.h 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/06/19. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import "UnityAppController.h" 16 | #import "DisplayManager.h" 17 | #import "TwitterActivity.h" 18 | 19 | 20 | @interface VideoCreator : NSObject 21 | 22 | typedef enum { 23 | VideoCreatorErrorVideoAssetEmpty, 24 | VideoCreatorErrorStatusError, 25 | } VideoCreatorErrorCode; 26 | 27 | typedef enum { 28 | VideoCreatorImageAlignmentTopCenter = 1, 29 | VideoCreatorImageAlignmentTopLeft, 30 | VideoCreatorImageAlignmentTopRight, 31 | VideoCreatorImageAlignmentBottomCenter, 32 | VideoCreatorImageAlignmentBottomLeft, 33 | VideoCreatorImageAlignmentBottomRight, 34 | } VideoCreatorImageAlignment; 35 | 36 | 37 | @property (nonatomic) NSString *outputFilePath; 38 | @property (nonatomic) int fps; 39 | @property (nonatomic) int frameCounter; 40 | 41 | - (id)initWithOptions:(NSString *)outputFilePath fps:(int)fps; 42 | 43 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer; 44 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer frameCounter:(int)frameCounter; 45 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer overlayImage:(CIImage *)overlayImage overlayFrame:(CGRect)overlayFrame; 46 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer overlayImage:(CIImage *)overlayImage overlayFrame:(CGRect)overlayFrame frameCounter:(int)frameCounter; 47 | - (void)initWriter:(int)width height:(int)height; 48 | - (void)finalizeWriter:(void (^)(void))completion; 49 | - (BOOL)isInitialized; 50 | 51 | + (CVPixelBufferRef)getPixelBufferFromCGImage:(CGImageRef)image imageRect:(CGRect)imageRect bgColor:(UIColor *)bgColor; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/VideoCreator.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97ca8c1f525ca419a91b3f8fab898afa 3 | timeCreated: 1467283734 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 1 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | userData: 19 | assetBundleName: 20 | assetBundleVariant: 21 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/VideoCreator.m: -------------------------------------------------------------------------------- 1 | // 2 | // VideoCreator.m 3 | // Unity-iPhone 4 | // 5 | // Created by tkyaji on 2016/06/19. 6 | // 7 | // 8 | 9 | #import "VideoCreator.h" 10 | 11 | #define ErrorDomain @"com.tkyaji.videocreator" 12 | #define MAX_SIDE_LENGTH 640 13 | 14 | @implementation VideoCreator { 15 | AVAssetWriter *_videoWriter; 16 | AVAssetWriterInput *_videoInput; 17 | AVAssetWriterInput *_audioInput; 18 | AVAssetWriterInputPixelBufferAdaptor *_adaptor; 19 | int _frameCount; 20 | CIContext *_ciContext; 21 | } 22 | 23 | - (id)initWithOptions:(NSString *)outputFilePath fps:(int)fps { 24 | if (self = [super init]) { 25 | self.outputFilePath = outputFilePath; 26 | self.fps = fps; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer { 32 | [self appendPixelBuffer:pixelBuffer frameCounter:1]; 33 | } 34 | 35 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer frameCounter:(int)frameCounter { 36 | CMTime frameTime = CMTimeMake(_frameCount, self.fps); 37 | 38 | if (!_adaptor.assetWriterInput.readyForMoreMediaData) { 39 | return; 40 | } 41 | 42 | if (![_adaptor appendPixelBuffer:pixelBuffer withPresentationTime:frameTime]) { 43 | NSLog(@"[RecShareManager] AVAssetWriterInputPixelBufferAdaptor appendPixelBuffer -> failed"); 44 | } 45 | 46 | _frameCount += frameCounter; 47 | } 48 | 49 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer overlayImage:(CIImage *)overlayImage overlayFrame:(CGRect)overlayFrame { 50 | [self appendPixelBuffer:pixelBuffer overlayImage:overlayImage overlayFrame:overlayFrame frameCounter:1]; 51 | } 52 | 53 | - (void)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer overlayImage:(CIImage *)overlayImage overlayFrame:(CGRect)overlayFrame frameCounter:(int)frameCounter { 54 | 55 | int bufferW = (int)CVPixelBufferGetWidth(pixelBuffer); 56 | int bufferH = (int)CVPixelBufferGetHeight(pixelBuffer); 57 | 58 | CVPixelBufferRef pixelBufferCopy = NULL; 59 | if (CVPixelBufferCreate(kCFAllocatorDefault, bufferW, bufferH, kCVPixelFormatType_32BGRA, NULL, &pixelBufferCopy) == kCVReturnSuccess) { 60 | CVPixelBufferLockBaseAddress(pixelBuffer, 0); 61 | CVPixelBufferLockBaseAddress(pixelBufferCopy, 0); 62 | 63 | uint8_t *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer); 64 | uint8_t *copyBaseAddress = CVPixelBufferGetBaseAddress(pixelBufferCopy); 65 | memcpy(copyBaseAddress, baseAddress, bufferH * CVPixelBufferGetBytesPerRow(pixelBuffer)); 66 | 67 | [_ciContext render:overlayImage toCVPixelBuffer:pixelBufferCopy bounds:overlayFrame colorSpace:CGColorSpaceCreateDeviceRGB()]; 68 | 69 | [self appendPixelBuffer:pixelBufferCopy frameCounter:frameCounter]; 70 | 71 | CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 72 | CVPixelBufferUnlockBaseAddress(pixelBufferCopy, 0); 73 | 74 | CVPixelBufferRelease(pixelBufferCopy); 75 | 76 | } else { 77 | [self appendPixelBuffer:pixelBuffer frameCounter:frameCounter]; 78 | } 79 | } 80 | 81 | - (void)initWriter:(int)width height:(int)height { 82 | if (width < height) { 83 | width = round((double)MAX_SIDE_LENGTH / 10 / height * width) * 10; 84 | height = MAX_SIDE_LENGTH; 85 | } else { 86 | height = round((double)MAX_SIDE_LENGTH / 10 / width * height) * 10; 87 | width = MAX_SIDE_LENGTH; 88 | } 89 | 90 | if ([[NSFileManager defaultManager] fileExistsAtPath:self.outputFilePath]) { 91 | [[NSFileManager defaultManager] removeItemAtPath:self.outputFilePath error:nil]; 92 | } 93 | NSURL *url = [NSURL fileURLWithPath:self.outputFilePath]; 94 | 95 | NSError *error = nil; 96 | AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:url fileType:AVFileTypeMPEG4 error:&error]; 97 | if (error) { 98 | NSLog(@"[RecShareManager] %@", error.localizedDescription); 99 | return; 100 | } 101 | 102 | AVAssetWriterInput *videoInput = 103 | [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo 104 | outputSettings:@{ 105 | AVVideoCodecKey : AVVideoCodecH264, 106 | AVVideoWidthKey : @(width), 107 | AVVideoHeightKey: @(height), 108 | }]; 109 | [videoWriter addInput:videoInput]; 110 | 111 | AVAssetWriterInputPixelBufferAdaptor *adaptor = 112 | [AVAssetWriterInputPixelBufferAdaptor 113 | assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoInput 114 | sourcePixelBufferAttributes:@{(NSString *)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA), 115 | (NSString *)kCVPixelBufferWidthKey: @(width), 116 | (NSString *)kCVPixelBufferHeightKey: @(height), 117 | }]; 118 | videoInput.expectsMediaDataInRealTime = YES; 119 | 120 | // slow in the first call 121 | if (![videoWriter startWriting]) { 122 | NSLog(@"[RecShareManager] AVAssetWriter startWriting -> failed"); 123 | return; 124 | } 125 | 126 | [videoWriter startSessionAtSourceTime:kCMTimeZero]; 127 | 128 | _videoWriter = videoWriter; 129 | _videoInput = videoInput; 130 | _adaptor = adaptor; 131 | 132 | NSDictionary *contextOptions = [NSDictionary dictionaryWithObjectsAndKeys: 133 | [NSNumber numberWithBool:NO],kCIContextUseSoftwareRenderer,nil]; 134 | _ciContext = [CIContext contextWithOptions:contextOptions]; 135 | 136 | return; 137 | } 138 | 139 | - (void)finalizeWriter:(void (^)(void))completion { 140 | if (!_adaptor) { 141 | return; 142 | } 143 | 144 | [_videoInput markAsFinished]; 145 | [_audioInput markAsFinished]; 146 | 147 | CMTime frameTime = CMTimeMake(_frameCount, self.fps); 148 | [_videoWriter endSessionAtSourceTime:frameTime]; 149 | 150 | float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; 151 | [_videoWriter finishWritingWithCompletionHandler:^{ 152 | if (osVersion >= 9.0) { 153 | [self finalizeVars:completion]; 154 | } 155 | }]; 156 | 157 | CVPixelBufferPoolRelease(_adaptor.pixelBufferPool); 158 | 159 | if (osVersion < 9.0) { 160 | [self checkFinalizeWriter:completion]; 161 | } 162 | } 163 | 164 | - (void)checkFinalizeWriter:(void (^)(void))completion { 165 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 166 | if (_videoWriter.status == AVAssetExportSessionStatusExporting || _videoWriter.status == AVAssetExportSessionStatusCompleted) { 167 | [self finalizeVars:completion]; 168 | } else { 169 | [self checkFinalizeWriter:completion]; 170 | } 171 | }); 172 | } 173 | 174 | - (void)finalizeVars:(void (^)(void))completion { 175 | if (completion) { 176 | completion(); 177 | } 178 | _adaptor = nil; 179 | _videoWriter = nil; 180 | _videoInput = nil; 181 | _frameCount = 0; 182 | } 183 | 184 | - (BOOL)isInitialized { 185 | return (_adaptor != nil); 186 | } 187 | 188 | + (CVPixelBufferRef)getPixelBufferFromCGImage:(CGImageRef)image imageRect:(CGRect)imageRect bgColor:(UIColor *)bgColor { 189 | 190 | CGSize screenSize = [UIScreen mainScreen].nativeBounds.size; 191 | 192 | NSDictionary *options = @{(__bridge NSString *)kCVPixelBufferCGImageCompatibilityKey: @(NO), 193 | (__bridge NSString *)kCVPixelBufferCGBitmapContextCompatibilityKey: @(NO) 194 | }; 195 | 196 | CVPixelBufferRef pixelBuffer; 197 | CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, screenSize.width, screenSize.height, 198 | kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef)options, 199 | &pixelBuffer); 200 | if (status != kCVReturnSuccess) { 201 | return NULL; 202 | } 203 | 204 | [VideoCreator writeImageToPixelBuffer:image imageRect:imageRect bgColor:bgColor pixelBuffer:pixelBuffer]; 205 | 206 | return pixelBuffer; 207 | } 208 | 209 | + (void)writeImageToPixelBuffer:(CGImageRef)image imageRect:(CGRect)imageRect bgColor:(UIColor *)bgColor pixelBuffer:(CVPixelBufferRef)pixelBuffer { 210 | 211 | size_t width = CVPixelBufferGetWidth(pixelBuffer); 212 | size_t height = CVPixelBufferGetHeight(pixelBuffer); 213 | 214 | CVPixelBufferLockBaseAddress(pixelBuffer, 0); 215 | void *data = CVPixelBufferGetBaseAddress(pixelBuffer); 216 | CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 217 | CGContextRef context = CGBitmapContextCreate(data, width, height, 218 | 8, CVPixelBufferGetBytesPerRow(pixelBuffer), 219 | rgbColorSpace, kCGImageAlphaPremultipliedFirst); 220 | 221 | if (bgColor) { 222 | CGContextSetFillColorWithColor(context, bgColor.CGColor); 223 | CGContextFillRect(context, CGRectMake(0, 0, width, height)); 224 | } 225 | 226 | CGContextDrawImage(context, imageRect, image); 227 | CGColorSpaceRelease(rgbColorSpace); 228 | CGContextRelease(context); 229 | CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); 230 | } 231 | 232 | @end 233 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Plugins/iOS/RecShare/VideoCreator.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9770d0d2a3e8c444c93337d858d7f2f7 3 | timeCreated: 1467283734 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | iOS: 19 | enabled: 1 20 | settings: {} 21 | tvOS: 22 | enabled: 1 23 | settings: {} 24 | userData: 25 | assetBundleName: 26 | assetBundleVariant: 27 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa323db5b93b645e4a2ba9ea32e04ecc 3 | folderAsset: yes 4 | timeCreated: 1465913542 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Cube.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class Cube : MonoBehaviour { 4 | 5 | private Vector3 toPosition = new Vector3(0f, 3f, 0f); 6 | 7 | void Update () { 8 | if (this.toPosition.y - transform.position.y <= 0.1f) { 9 | this.toPosition = new Vector3(0f, -3f, 0f); 10 | } else if (transform.position.y - this.toPosition.y <= 0.1f) { 11 | this.toPosition = new Vector3(0f, 3f, 0f); 12 | } 13 | transform.position = transform.position + this.toPosition * 1f * Time.deltaTime; 14 | transform.Rotate (new Vector3 (Time.deltaTime * 30f, 10f, 5f)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Cube.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5b0c11062eeb248229836c52335938a9 3 | timeCreated: 1465916344 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Material.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Sample/Material.mat -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Material.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bcb26e75f6d16443ca2038d4bdd3b6d0 3 | timeCreated: 1465916287 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Sample.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | public class Sample : MonoBehaviour { 5 | 6 | [SerializeField] 7 | private Button StartButton; 8 | 9 | [SerializeField] 10 | private Button StopButton; 11 | 12 | [SerializeField] 13 | private Button PauseButton; 14 | 15 | [SerializeField] 16 | private Button ResumeButton; 17 | 18 | [SerializeField] 19 | private Button PlayButton; 20 | 21 | [SerializeField] 22 | private Button ShareButton; 23 | 24 | [SerializeField] 25 | private GameObject ScreenShotRawImageGO; 26 | 27 | 28 | void Start() { 29 | RecShare.Initialize(); 30 | 31 | RecShare.SetFirstImage("title", new Vector2(320f, 67f), 2f, Color.white); 32 | RecShare.SetLastImage("title", new Vector2(320f, 67f), 2f, Color.white); 33 | RecShare.SetOverlayImage("logo", new Vector2(300f, 30f), RecShare.Alignment.BottomRight); 34 | } 35 | 36 | public void StartButtonClick() { 37 | RecShare.StartRecording(); 38 | 39 | this.StartButton.interactable = false; 40 | this.StopButton.interactable = true; 41 | this.PauseButton.interactable = true; 42 | this.ResumeButton.interactable = false; 43 | this.PlayButton.interactable = false; 44 | this.ShareButton.interactable = false; 45 | 46 | this.ScreenShotRawImageGO.SetActive(false); 47 | var tex2d = this.ScreenShotRawImageGO.GetComponent().texture; 48 | if (tex2d != null) { 49 | Destroy(tex2d); 50 | } 51 | this.ScreenShotRawImageGO.GetComponent().texture = null; 52 | } 53 | 54 | public void StopButtonClick() { 55 | RecShare.StopRecording(() => { 56 | float endTime = RecShare.GetVideoDuration(); 57 | this.ScreenShotRawImageGO.GetComponent().texture = RecShare.GetScreenShot(endTime); 58 | this.ScreenShotRawImageGO.SetActive(true); 59 | 60 | this.StopButton.interactable = false; 61 | this.PauseButton.interactable = false; 62 | this.ResumeButton.interactable = false; 63 | this.StartButton.interactable = true; 64 | this.PlayButton.interactable = true; 65 | this.ShareButton.interactable = true; 66 | }); 67 | } 68 | 69 | public void PauseButtonClick() { 70 | RecShare.PauseRecording(); 71 | 72 | this.PauseButton.interactable = false; 73 | this.ResumeButton.interactable = true; 74 | } 75 | 76 | public void ResumeButtonClick() { 77 | RecShare.ResumeRecording(); 78 | 79 | this.PauseButton.interactable = true; 80 | this.ResumeButton.interactable = false; 81 | } 82 | 83 | public void PlayButtonClick() { 84 | RecShare.ShowVideoPlayer(); 85 | } 86 | 87 | public void ShareButtonClick() { 88 | RecShare.ShowSharingModal(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Sample.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a2f17c70c1e7c4b0ebc26eb6b920ebec 3 | timeCreated: 1465918674 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Sample.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShare/Assets/RecShare/Sample/Sample.unity -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Sample/Sample.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3dd6f199a320c4969994c95079694ecd 3 | timeCreated: 1465913552 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ad7b5abc469e4ea993a3b0d348db061 3 | folderAsset: yes 4 | timeCreated: 1470611737 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts/Stub.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 03c617fb485194970871021e539e00ee 3 | folderAsset: yes 4 | timeCreated: 1465919365 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts/Stub/RecShare.cs: -------------------------------------------------------------------------------- 1 | #if !UNITY_IOS || UNITY_EDITOR 2 | 3 | using UnityEngine; 4 | using System; 5 | 6 | public class RecShare { 7 | 8 | public enum Alignment { 9 | TopCenter = 1, 10 | TopLeft, 11 | TopRight, 12 | BottomCenter, 13 | BottomLeft, 14 | BottomRight, 15 | } 16 | 17 | 18 | public static void Initialize() { 19 | Debug.Log("Initialize"); 20 | } 21 | 22 | public static void StartRecording() { 23 | Debug.Log("StartRecording"); 24 | } 25 | 26 | public static void StopRecording(Action completion = null) { 27 | Debug.Log("StopRecording"); 28 | } 29 | 30 | public static void PauseRecording() { 31 | Debug.Log("PauseRecording"); 32 | } 33 | 34 | public static void ResumeRecording() { 35 | Debug.Log("ResumeRecording"); 36 | } 37 | 38 | public static bool IsRecording() { 39 | Debug.Log("IsRecording"); 40 | return false; 41 | } 42 | 43 | public static bool IsPaused() { 44 | Debug.Log("IsPaused"); 45 | return false; 46 | } 47 | 48 | public static void ShowSharingModal(string text = "") { 49 | Debug.Log("ShowSharingModal : " + text); 50 | } 51 | 52 | public static void ShowVideoPlayer() { 53 | Debug.Log("ShowVideoPlayer"); 54 | } 55 | 56 | public static string GetVideoFilePath() { 57 | Debug.Log("GetVideoFilePath"); 58 | return null; 59 | } 60 | 61 | public static float GetVideoDuration() { 62 | Debug.Log("GetVideoDuration"); 63 | return 0f; 64 | } 65 | 66 | public static Texture2D GetScreenShot(float seconds) { 67 | Debug.Log("GetScreenShot : " + seconds); 68 | return null; 69 | } 70 | 71 | public static void SetFrameInterval(int frameInterval) { 72 | Debug.Log("SetFrameInterval : " + frameInterval); 73 | } 74 | 75 | public static void SetFirstImage(Texture2D tex2d, Vector2 imageSize, float displayTime) { 76 | Debug.Log("SetFirstImage"); 77 | } 78 | 79 | public static void SetFirstImage(Texture2D tex2d, Vector2 imageSize, float displayTime, Color bgColor) { 80 | Debug.Log("SetFirstImage"); 81 | } 82 | 83 | public static void SetFirstImage(string imageName, Vector2 imageSize, float displayTime, Color bgColor) { 84 | Debug.Log("SetFirstImage"); 85 | } 86 | 87 | public static void SetLastImage(Texture2D tex2d, Vector2 imageSize, float displayTime) { 88 | Debug.Log("SetLastImage"); 89 | } 90 | 91 | public static void SetLastImage(Texture2D tex2d, Vector2 imageSize, float displayTime, Color bgColor) { 92 | Debug.Log("SetLastImage"); 93 | } 94 | 95 | public static void SetLastImage(string imageName, Vector2 imageSize, float displayTime, Color bgColor) { 96 | Debug.Log("SetLastImage"); 97 | } 98 | 99 | public static void SetOverlayImage(Texture2D tex2d, Vector2 imageSize, RecShare.Alignment alignment) { 100 | Debug.Log("SetOverlayImage"); 101 | } 102 | 103 | public static void SetOverlayImage(string imageName, Vector2 imageSize, RecShare.Alignment alignment) { 104 | Debug.Log("SetOverlayImage"); 105 | } 106 | 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts/Stub/RecShare.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 841e23dab3c8a4eecaa6118fb48950be 3 | timeCreated: 1465919443 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b29b1bd3702c49f585f9c49c1aa48d4 3 | folderAsset: yes 4 | timeCreated: 1465919355 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts/iOS/RecShare.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_IOS && !UNITY_EDITOR 2 | 3 | using UnityEngine; 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using AOT; 7 | 8 | 9 | public class RecShare { 10 | 11 | public enum Alignment { 12 | TopCenter = 1, 13 | TopLeft, 14 | TopRight, 15 | BottomCenter, 16 | BottomLeft, 17 | BottomRight, 18 | } 19 | 20 | 21 | public class RecShareCallback { 22 | private Action callback; 23 | public RecShareCallback(Action callback) { 24 | this.callback = callback; 25 | } 26 | public void Invoke() { 27 | if (this.callback != null) { 28 | this.callback.Invoke(); 29 | } 30 | } 31 | } 32 | 33 | delegate void CompletionDelegate(IntPtr callbackPtr, bool ret); 34 | 35 | [MonoPInvokeCallback(typeof(CompletionDelegate))] 36 | private static void csCompletion(IntPtr callbackPtr, bool ret) { 37 | GCHandle handle = (GCHandle)callbackPtr; 38 | var callback = (RecShareCallback)handle.Target; 39 | callback.Invoke(); 40 | handle.Free(); 41 | 42 | } 43 | 44 | [DllImport("__Internal")] 45 | private static extern void _RecSharePlugin_initialize(); 46 | 47 | [DllImport("__Internal")] 48 | private static extern void _RecSharePlugin_startRecoding(); 49 | 50 | [DllImport("__Internal")] 51 | private static extern void _RecSharePlugin_stopRecording(IntPtr instance, CompletionDelegate completion); 52 | 53 | [DllImport("__Internal")] 54 | private static extern void _RecSharePlugin_pauseRecording(); 55 | 56 | [DllImport("__Internal")] 57 | private static extern void _RecSharePlugin_resumeRecording(); 58 | 59 | [DllImport("__Internal")] 60 | private static extern bool _RecSharePlugin_isRecording(); 61 | 62 | [DllImport("__Internal")] 63 | private static extern bool _RecSharePlugin_isPaused(); 64 | 65 | [DllImport("__Internal")] 66 | private static extern void _RecSharePlugin_showSharingModal(string text); 67 | 68 | [DllImport("__Internal")] 69 | private static extern void _RecSharePlugin_showVideoPlayer(); 70 | 71 | [DllImport("__Internal")] 72 | private static extern string _RecSharePlugin_getVideoFilePath(); 73 | 74 | [DllImport("__Internal")] 75 | private static extern float _RecSharePlugin_getVideoDuration(); 76 | 77 | [DllImport("__Internal")] 78 | private static extern void _RecSharePlugin_getScreenShotImage(float seconds, out IntPtr byteArrPtr, out int size); 79 | 80 | [DllImport("__Internal")] 81 | private static extern void _RecSharePlugin_setFrameInterval(int frameInterval); 82 | 83 | [DllImport("__Internal")] 84 | private static extern void _RecSharePlugin_setFirstImage_data( 85 | byte[] bytes, int length, float width, float height, float r, float g, float b, float displayTime); 86 | 87 | [DllImport("__Internal")] 88 | private static extern void _RecSharePlugin_setFirstImage_imageName( 89 | string imageName, float width, float height, float r, float g, float b, float displayTime); 90 | 91 | [DllImport("__Internal")] 92 | private static extern void _RecSharePlugin_setLastImage_data( 93 | byte[] bytes, int length, float width, float height, float r, float g, float b, float displayTime); 94 | 95 | [DllImport("__Internal")] 96 | private static extern void _RecSharePlugin_setLastImage_imageName( 97 | string imageName, float width, float height, float r, float g, float b, float displayTime); 98 | 99 | [DllImport("__Internal")] 100 | private static extern void _RecSharePlugin_setOverlayImage_data(byte[] bytes, int length, float width, float height, int alignment); 101 | 102 | [DllImport("__Internal")] 103 | private static extern void _RecSharePlugin_setOverlayImage_imageName(string imageName, float width, float height, int alignment); 104 | 105 | 106 | 107 | public static void Initialize() { 108 | _RecSharePlugin_initialize(); 109 | } 110 | 111 | public static void StartRecording() { 112 | _RecSharePlugin_startRecoding(); 113 | } 114 | 115 | public static void StopRecording(Action completion = null) { 116 | var callback = new RecShareCallback(completion); 117 | IntPtr callbackPtr = (IntPtr)GCHandle.Alloc(callback); 118 | _RecSharePlugin_stopRecording(callbackPtr, csCompletion); 119 | } 120 | 121 | public static void PauseRecording() { 122 | _RecSharePlugin_pauseRecording(); 123 | } 124 | 125 | public static void ResumeRecording() { 126 | _RecSharePlugin_resumeRecording(); 127 | } 128 | 129 | public static bool IsRecording() { 130 | return _RecSharePlugin_isRecording(); 131 | } 132 | 133 | public static bool IsPaused() { 134 | return _RecSharePlugin_isPaused(); 135 | } 136 | 137 | public static void ShowSharingModal(string text = "") { 138 | _RecSharePlugin_showSharingModal(text); 139 | } 140 | 141 | public static void ShowVideoPlayer() { 142 | _RecSharePlugin_showVideoPlayer(); 143 | } 144 | 145 | public static string GetVideoFilePath() { 146 | return _RecSharePlugin_getVideoFilePath(); 147 | } 148 | 149 | public static float GetVideoDuration() { 150 | return _RecSharePlugin_getVideoDuration(); 151 | } 152 | 153 | public static Texture2D GetScreenShot(float seconds) { 154 | IntPtr byteArrPtr = IntPtr.Zero; 155 | int size = 0; 156 | 157 | _RecSharePlugin_getScreenShotImage(seconds, out byteArrPtr, out size); 158 | 159 | byte[] arr = new byte[size]; 160 | Marshal.Copy(byteArrPtr, arr, 0, size); 161 | 162 | var tex2d = new Texture2D(Screen.width, Screen.height); 163 | tex2d.LoadImage(arr); 164 | 165 | return tex2d; 166 | } 167 | 168 | public static void SetFrameInterval(int frameInterval) { 169 | _RecSharePlugin_setFrameInterval(frameInterval); 170 | } 171 | 172 | public static void SetFirstImage(Texture2D tex2d, Vector2 imageSize, float displayTime) { 173 | SetFirstImage(tex2d, imageSize, displayTime, Color.black); 174 | } 175 | 176 | public static void SetFirstImage(Texture2D tex2d, Vector2 imageSize, float displayTime, Color bgColor) { 177 | byte[] bytes = tex2d.EncodeToPNG(); 178 | _RecSharePlugin_setFirstImage_data(bytes, bytes.Length, imageSize.x, imageSize.y, bgColor.r, bgColor.g, bgColor.b, displayTime); 179 | } 180 | 181 | public static void SetFirstImage(string imageName, Vector2 imageSize, float displayTime, Color bgColor) { 182 | _RecSharePlugin_setFirstImage_imageName(imageName, imageSize.x, imageSize.y, bgColor.r, bgColor.g, bgColor.b, displayTime); 183 | } 184 | 185 | public static void SetLastImage(Texture2D tex2d, Vector2 imageSize, float displayTime) { 186 | SetLastImage(tex2d, imageSize, displayTime, Color.black); 187 | } 188 | 189 | public static void SetLastImage(Texture2D tex2d, Vector2 imageSize, float displayTime, Color bgColor) { 190 | byte[] bytes = tex2d.EncodeToPNG(); 191 | _RecSharePlugin_setLastImage_data(bytes, bytes.Length, imageSize.x, imageSize.y, bgColor.r, bgColor.g, bgColor.b, displayTime); 192 | } 193 | 194 | public static void SetLastImage(string imageName, Vector2 imageSize, float displayTime, Color bgColor) { 195 | _RecSharePlugin_setLastImage_imageName(imageName, imageSize.x, imageSize.y, bgColor.r, bgColor.g, bgColor.b, displayTime); 196 | } 197 | 198 | public static void SetOverlayImage(Texture2D tex2d, Vector2 imageSize, RecShare.Alignment alignment) { 199 | byte[] bytes = tex2d.EncodeToPNG(); 200 | _RecSharePlugin_setOverlayImage_data(bytes, bytes.Length, imageSize.x, imageSize.y, (int)alignment); 201 | } 202 | 203 | public static void SetOverlayImage(string imageName, Vector2 imageSize, RecShare.Alignment alignment) { 204 | _RecSharePlugin_setOverlayImage_imageName(imageName, imageSize.x, imageSize.y, (int)alignment); 205 | } 206 | 207 | } 208 | 209 | #endif 210 | -------------------------------------------------------------------------------- /RecShare/Assets/RecShare/Scripts/iOS/RecShare.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5a21dde7a56d4eb2a402e4cc2b97352 3 | timeCreated: 1462035224 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /RecShareSample.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkyaji/UnityRecShare/03c1bacd332502597401da6ed8cb721d9b3458a0/RecShareSample.unitypackage --------------------------------------------------------------------------------