Commit bd6acc3548ce4666792ec956fdaea3fb59c51f00
1 parent
30f316ce
WIP con streaming... aun no va
Showing
7 changed files
with
236 additions
and
100 deletions
res/layout/main_activity.xml
... | ... | @@ -11,16 +11,14 @@ |
11 | 11 | |
12 | 12 | <ImageButton |
13 | 13 | android:id="@+id/button" |
14 | - android:layout_width="256dp" | |
15 | - android:layout_height="256dp" | |
14 | + android:layout_width="192dip" | |
15 | + android:layout_height="192dip" | |
16 | 16 | android:layout_centerHorizontal="true" |
17 | 17 | android:layout_centerVertical="true" |
18 | 18 | android:background="@drawable/startbuttontoggle" |
19 | 19 | android:contentDescription="@string/startbuttondescription" |
20 | 20 | android:focusable="false" |
21 | 21 | android:focusableInTouchMode="false" |
22 | - android:maxHeight="@dimen/lesize" | |
23 | - android:maxWidth="@dimen/lesize" | |
24 | 22 | android:scaleType="fitCenter" /> |
25 | 23 | |
26 | 24 | <TextView | ... | ... |
res/values/strings.xml
... | ... | @@ -29,5 +29,6 @@ |
29 | 29 | <string name="alertVitamioNotInstalled">Alerta! Llibreries de Vitamio no instal·lades!</string> |
30 | 30 | <string name="alertLogoDescription">Alerta!</string> |
31 | 31 | <string name="itemType">Item type</string> |
32 | + <string name="buffering_text">Buffering...</string> | |
32 | 33 | |
33 | 34 | </resources> |
34 | 35 | \ No newline at end of file | ... | ... |
src/com/upc/pbe/upcnews/Directoris.java
... | ... | @@ -6,8 +6,6 @@ import java.util.ArrayList; |
6 | 6 | import java.util.concurrent.ExecutionException; |
7 | 7 | |
8 | 8 | import android.app.Activity; |
9 | -import android.app.DownloadManager; | |
10 | -import android.content.Context; | |
11 | 9 | import android.content.Intent; |
12 | 10 | import android.os.Bundle; |
13 | 11 | import android.util.Log; |
... | ... | @@ -61,12 +59,10 @@ public class Directoris extends Activity implements OnItemClickListener |
61 | 59 | } |
62 | 60 | catch (InterruptedException e) |
63 | 61 | { |
64 | - // TODO Auto-generated catch block | |
65 | 62 | e.printStackTrace(); |
66 | 63 | } |
67 | 64 | catch (ExecutionException e) |
68 | 65 | { |
69 | - // TODO Auto-generated catch block | |
70 | 66 | e.printStackTrace(); |
71 | 67 | } |
72 | 68 | catch (IOException e) |
... | ... | @@ -106,8 +102,7 @@ public class Directoris extends Activity implements OnItemClickListener |
106 | 102 | ArrayList<ParentList> m3u8parsed = p.parseFile(playlist); |
107 | 103 | Log.d(TAG, "Parsing completat"); |
108 | 104 | //Creem un gestor HLS |
109 | - DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); | |
110 | - HLS h = new HLS(m3u8parsed,((UpcApp)getApplication()).getLocalPath(), manager); | |
105 | + HLS h = new HLS(m3u8parsed,((UpcApp)getApplication()).getLocalPath()); | |
111 | 106 | ((UpcApp)getApplication()).setHLS(h); |
112 | 107 | //Iniciem la reproduccio |
113 | 108 | Intent mIntent = new Intent(this, VideoActivity.class); |
... | ... | @@ -142,12 +137,10 @@ public class Directoris extends Activity implements OnItemClickListener |
142 | 137 | } |
143 | 138 | catch (InterruptedException e1) |
144 | 139 | { |
145 | - // TODO Auto-generated catch block | |
146 | 140 | e1.printStackTrace(); |
147 | 141 | } |
148 | 142 | catch (ExecutionException e1) |
149 | 143 | { |
150 | - // TODO Auto-generated catch block | |
151 | 144 | e1.printStackTrace(); |
152 | 145 | } |
153 | 146 | } | ... | ... |
src/com/upc/pbe/upcnews/HLS.java
1 | 1 | package com.upc.pbe.upcnews; |
2 | 2 | |
3 | +import io.vov.vitamio.widget.VideoView; | |
4 | + | |
5 | +import java.io.BufferedInputStream; | |
3 | 6 | import java.io.File; |
7 | +import java.io.FileOutputStream; | |
4 | 8 | import java.io.IOException; |
9 | +import java.net.MalformedURLException; | |
10 | +import java.net.URL; | |
5 | 11 | import java.util.ArrayList; |
6 | 12 | |
7 | -import android.app.DownloadManager; | |
8 | -import android.app.DownloadManager.Request; | |
13 | +import android.app.AlertDialog; | |
9 | 14 | import android.content.Context; |
10 | 15 | import android.net.TrafficStats; |
11 | -import android.net.Uri; | |
16 | +import android.os.AsyncTask; | |
12 | 17 | import android.util.Log; |
18 | +import android.view.LayoutInflater; | |
19 | +import android.widget.Toast; | |
13 | 20 | |
14 | 21 | //Gestor del protocol HTTP Live Streaming |
15 | 22 | public class HLS |
16 | 23 | { |
17 | - | |
24 | + private static long TRIGGER_PLAY; | |
18 | 25 | private static final String TAG = "HLS"; |
19 | 26 | private ArrayList<ParentList> videos; |
20 | 27 | private ArrayList<Segment> segments; |
... | ... | @@ -24,11 +31,15 @@ public class HLS |
24 | 31 | private int currentSegment; |
25 | 32 | private boolean endReached; |
26 | 33 | private String localFolder; |
27 | - private DownloadManager dm; | |
28 | 34 | private BandwidthMeasurer bm; |
35 | + private boolean started; | |
36 | + private boolean ended; | |
37 | + private long totalDownloaded; | |
38 | + private VideoView video; | |
39 | + private VideoActivity vActivity; | |
29 | 40 | |
30 | 41 | |
31 | - public HLS(ArrayList<ParentList> parsed, String localFolder, DownloadManager manager) | |
42 | + public HLS(ArrayList<ParentList> parsed, String localFolder) | |
32 | 43 | { |
33 | 44 | // Neteja el directori i inicialitza les variables |
34 | 45 | File dir = new File(localFolder); |
... | ... | @@ -45,8 +56,47 @@ public class HLS |
45 | 56 | endReached = false; |
46 | 57 | this.localFolder = localFolder; |
47 | 58 | bm = new BandwidthMeasurer(); |
59 | + started = ended = false; | |
60 | + totalDownloaded = 0; | |
48 | 61 | } |
49 | 62 | |
63 | + public void setBufferSize() | |
64 | + { | |
65 | + /* | |
66 | + * Supondremos todos los segmentos de misma duración | |
67 | + */ | |
68 | + if(qualities.get(currentQuality).getQuality() == -1) | |
69 | + { | |
70 | + /* | |
71 | + * No nos dicen la calidad, la pondremos al conocer la longitud del primer segmento | |
72 | + */ | |
73 | + TRIGGER_PLAY = -1; | |
74 | + } | |
75 | + else | |
76 | + { | |
77 | + //15 segundos de cancha para empezar | |
78 | + TRIGGER_PLAY = (long) (15 * qualities.get(currentQuality).getQuality()/8e3); | |
79 | + } | |
80 | + | |
81 | + } | |
82 | + | |
83 | + public void quitPlayer(VideoActivity v) | |
84 | + { | |
85 | + video.stopPlayback(); | |
86 | + v.finish(); | |
87 | + return; | |
88 | + } | |
89 | + | |
90 | + public void setVideoViewer(VideoView v) | |
91 | + { | |
92 | + video = v; | |
93 | + } | |
94 | + | |
95 | + public void setVideoActivity(VideoActivity v) | |
96 | + { | |
97 | + vActivity = v; | |
98 | + } | |
99 | + | |
50 | 100 | public void loadVideo() |
51 | 101 | { |
52 | 102 | // Carrega la qualitat i, a partir d'aixo, el seguent segment |
... | ... | @@ -56,6 +106,7 @@ public class HLS |
56 | 106 | { |
57 | 107 | endReached = true; |
58 | 108 | } |
109 | + setBufferSize(); | |
59 | 110 | } |
60 | 111 | |
61 | 112 | public String next() throws IOException |
... | ... | @@ -71,59 +122,47 @@ public class HLS |
71 | 122 | } |
72 | 123 | Segment seg = segments.get(currentSegment++); |
73 | 124 | String path = localFolder+seg.getURL().substring(seg.getURL().lastIndexOf("/") + 1, seg.getURL().length()); |
74 | - if(!new File(path).exists()) //Para qué bajarlo dos veces? | |
125 | + Log.d(TAG, seg.getName() + " " + seg.getURL()); | |
126 | + return path; | |
127 | + } | |
128 | + | |
129 | + public void updateQuality(long bps) | |
130 | + { | |
131 | + if ((bps <= qualities.get(currentQuality).getQuality()) && (bps != -1)) | |
75 | 132 | { |
76 | - Log.d(TAG, seg.getName() + " " + seg.getURL()); | |
77 | - long startTime = System.currentTimeMillis(); | |
78 | - long segmentBytes = TrafficStats.getTotalRxBytes(); | |
79 | - descarregarguardar(seg.getURL(), localFolder); | |
80 | - double bps = bm.Measure(segmentBytes, startTime); | |
81 | - Log.d(TAG, "Velocitat actual (KB/s): " + (bps / 8e3)); | |
82 | - if ((bps <= qualities.get(currentQuality).getQuality()) && (bps != -1)) | |
133 | + int newQuality; | |
134 | + for(newQuality = 0; newQuality < qualities.size(); newQuality++) | |
83 | 135 | { |
84 | - int newQuality; | |
85 | - for(newQuality = 0; newQuality < qualities.size(); newQuality++) | |
86 | - { | |
87 | - if(bps >= qualities.get(newQuality).getQuality()) | |
88 | - { | |
89 | - break; | |
90 | - } | |
91 | - } | |
92 | - if(currentQuality != newQuality) | |
136 | + if(bps >= qualities.get(newQuality).getQuality()) | |
93 | 137 | { |
94 | - currentQuality = newQuality; | |
95 | - currentVideo--; //Corregimos el del loadVideo() | |
96 | - loadVideo(); //Cargamos la nueva calidad | |
138 | + break; | |
97 | 139 | } |
98 | 140 | } |
99 | - else if((bps > qualities.get(currentQuality).getQuality()) && (bps != -1)) | |
141 | + if(currentQuality != newQuality) | |
100 | 142 | { |
101 | - int newQuality; | |
102 | - for(newQuality = qualities.size()-1; newQuality > 0; newQuality--) | |
103 | - { | |
104 | - if(bps <= qualities.get(newQuality).getQuality()) | |
105 | - { | |
106 | - newQuality--; | |
107 | - break; | |
108 | - } | |
109 | - } | |
110 | - if(currentQuality != newQuality) | |
143 | + currentQuality = newQuality; | |
144 | + currentVideo--; //Corregimos el del loadVideo() | |
145 | + loadVideo(); //Cargamos la nueva calidad | |
146 | + } | |
147 | + } | |
148 | + else if((bps > qualities.get(currentQuality).getQuality()) && (bps != -1)) | |
149 | + { | |
150 | + int newQuality; | |
151 | + for(newQuality = qualities.size()-1; newQuality > 0; newQuality--) | |
152 | + { | |
153 | + if(bps <= qualities.get(newQuality).getQuality()) | |
111 | 154 | { |
112 | - currentQuality = newQuality; | |
113 | - currentVideo--; //Corregimos el del loadVideo() | |
114 | - loadVideo(); //Cargamos la nueva calidad | |
155 | + newQuality--; | |
156 | + break; | |
115 | 157 | } |
116 | 158 | } |
159 | + if(currentQuality != newQuality) | |
160 | + { | |
161 | + currentQuality = newQuality; | |
162 | + currentVideo--; //Corregimos el del loadVideo() | |
163 | + loadVideo(); //Cargamos la nueva calidad | |
164 | + } | |
117 | 165 | } |
118 | - return path; | |
119 | - } | |
120 | - | |
121 | - public void descarregarguardar(String url, String path) | |
122 | - { | |
123 | - Request req = new Request(Uri.parse(url)); | |
124 | - req.setVisibleInDownloadsUi(false); | |
125 | - req.setDestinationUri(Uri.parse("file://"+path + url.substring(url.lastIndexOf("/")+1, url.length()))); | |
126 | - dm.enqueue(req); | |
127 | 166 | } |
128 | 167 | |
129 | 168 | public String previous() throws IOException |
... | ... | @@ -136,9 +175,127 @@ public class HLS |
136 | 175 | seg = segments.get(currentSegment++); |
137 | 176 | return localFolder + seg.getURL().substring(seg.getURL().lastIndexOf("/") + 1, seg.getURL().length()); |
138 | 177 | } |
139 | - | |
140 | - public void startDownloadManager(Context ctx) | |
178 | + | |
179 | + public boolean hasEnded() | |
180 | + { | |
181 | + return ended; | |
182 | + } | |
183 | + | |
184 | + public void buffer() | |
185 | + { | |
186 | + video.stopPlayback(); | |
187 | + started = false; | |
188 | + } | |
189 | + | |
190 | + public void downloadSegment(String url) | |
141 | 191 | { |
142 | - dm = (DownloadManager) ctx.getSystemService("download"); | |
192 | + DescarregaSegment ds = new DescarregaSegment(vActivity); | |
193 | + try | |
194 | + { | |
195 | + ds.execute(new URL(url)); | |
196 | + } | |
197 | + catch (MalformedURLException e) | |
198 | + { | |
199 | + e.printStackTrace(); | |
200 | + } | |
201 | + } | |
202 | + | |
203 | + public class DescarregaSegment extends AsyncTask<URL, Integer, Long> | |
204 | + { | |
205 | + final static String TAG = "DescarregaSegment"; | |
206 | + private Context ctx; | |
207 | + private long bps; | |
208 | + AlertDialog alertDialog; | |
209 | + | |
210 | + public DescarregaSegment(Context c) | |
211 | + { | |
212 | + ctx = c; | |
213 | + bps = 0; | |
214 | + AlertDialog.Builder builder = new AlertDialog.Builder(vActivity); | |
215 | + LayoutInflater inflater = vActivity.getLayoutInflater(); | |
216 | + builder.setView(inflater.inflate(R.layout.buffering_dialog,null)); | |
217 | + alertDialog = builder.create(); | |
218 | + } | |
219 | + | |
220 | + | |
221 | + @Override | |
222 | + protected Long doInBackground(URL... urls) | |
223 | + { | |
224 | + if(!started) | |
225 | + { | |
226 | + alertDialog.show(); | |
227 | + } | |
228 | + Long downloaded = Long.valueOf(0); | |
229 | + long startTime = System.currentTimeMillis(); | |
230 | + long segmentBytes = TrafficStats.getTotalRxBytes(); | |
231 | + Log.d(TAG, "Velocitat actual (KB/s): " + (bps / 8e3)); | |
232 | + // Iniciem la connexi� i creem els Streams | |
233 | + try | |
234 | + { | |
235 | + FileOutputStream out = new FileOutputStream(localFolder + "video.ts"); | |
236 | + BufferedInputStream in = new BufferedInputStream(urls[0].openStream()); | |
237 | + Log.d(TAG, "\nDescarregant: \n"); | |
238 | + Log.d(TAG, ">> URL: " + urls[0]); | |
239 | + byte data[] = new byte[102400]; | |
240 | + int count; | |
241 | + while ((count = in.read(data)) != -1) | |
242 | + { | |
243 | + downloaded += count; | |
244 | + out.write(data, 0, count); | |
245 | + } | |
246 | + out.flush(); | |
247 | + out.close(); | |
248 | + in.close(); | |
249 | + bps = (long) bm.Measure(segmentBytes, startTime); | |
250 | + Log.d(TAG, "Descarrega finalitzada"); | |
251 | + } | |
252 | + catch(IOException e) | |
253 | + { | |
254 | + this.cancel(true); | |
255 | + Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_LONG).show(); | |
256 | + return Long.valueOf(-1); | |
257 | + } | |
258 | + return downloaded; | |
259 | + } | |
260 | + protected void onPostExecute(Long result) | |
261 | + { | |
262 | + totalDownloaded += result; | |
263 | + if(ended = true) | |
264 | + { | |
265 | + quitPlayer((VideoActivity) ctx); | |
266 | + } | |
267 | + if(TRIGGER_PLAY == -1) | |
268 | + { | |
269 | + long Bps = (long) (result/segments.get(currentSegment).getDuration()); | |
270 | + TRIGGER_PLAY = 15*Bps/1000; | |
271 | + } | |
272 | + if(!started && totalDownloaded >= TRIGGER_PLAY) | |
273 | + { | |
274 | + alertDialog.dismiss(); | |
275 | + started = true; | |
276 | + video.start(); | |
277 | + video.requestFocus(); | |
278 | + } | |
279 | + String newSegment = null; | |
280 | + try | |
281 | + { | |
282 | + updateQuality((long) bps); | |
283 | + newSegment = next(); | |
284 | + } | |
285 | + catch(IOException e) | |
286 | + { | |
287 | + Toast.makeText(ctx, "No s'ha trobat el segment", Toast.LENGTH_LONG).show(); | |
288 | + quitPlayer((VideoActivity) ctx); | |
289 | + } | |
290 | + if(newSegment.equals(null)) | |
291 | + { | |
292 | + ended = true; | |
293 | + } | |
294 | + else | |
295 | + { | |
296 | + downloadSegment(newSegment); | |
297 | + } | |
298 | + return; | |
299 | + } | |
143 | 300 | } |
144 | 301 | } |
145 | 302 | \ No newline at end of file | ... | ... |
src/com/upc/pbe/upcnews/MainActivity.java
... | ... | @@ -21,7 +21,8 @@ import android.widget.TextView; |
21 | 21 | import android.widget.Toast; |
22 | 22 | |
23 | 23 | //Finestra incial i activity principal del programa |
24 | -public class MainActivity extends Activity implements OnClickListener { | |
24 | +public class MainActivity extends Activity implements OnClickListener | |
25 | +{ | |
25 | 26 | |
26 | 27 | private final static String TAG = "Main"; |
27 | 28 | private static String html; |
... | ... | @@ -78,19 +79,18 @@ public class MainActivity extends Activity implements OnClickListener { |
78 | 79 | } |
79 | 80 | catch (InterruptedException e) |
80 | 81 | { |
81 | - // TODO Auto-generated catch block | |
82 | 82 | e.printStackTrace(); |
83 | 83 | } |
84 | 84 | catch (ExecutionException e) |
85 | 85 | { |
86 | - // TODO Auto-generated catch block | |
87 | 86 | e.printStackTrace(); |
88 | 87 | } |
89 | 88 | catch (MalformedURLException e) |
90 | 89 | { |
91 | 90 | Toast.makeText(this, "URL Malformada", Toast.LENGTH_LONG).show(); |
92 | 91 | } |
93 | - if(!html.equals("")) { | |
92 | + if(!html.equals("")) | |
93 | + { | |
94 | 94 | ((UpcApp) getApplication()).setDesc(html); |
95 | 95 | startActivity(new Intent(this, Directoris.class)); |
96 | 96 | } | ... | ... |
src/com/upc/pbe/upcnews/ParentList.java
... | ... | @@ -5,7 +5,6 @@ import java.util.ArrayList; |
5 | 5 | public class ParentList |
6 | 6 | { |
7 | 7 | private String ID; |
8 | - private int currentQuality; | |
9 | 8 | private String Type, Name; |
10 | 9 | private boolean Default; //Estos 3 ultimos son para los ext-x-media, los ext-x-stream lo IGNORAN |
11 | 10 | private ArrayList<Video> lists; //per cada qualitat |
... | ... | @@ -14,7 +13,6 @@ public class ParentList |
14 | 13 | public ParentList(String ID) |
15 | 14 | { |
16 | 15 | this.ID = ID; |
17 | - currentQuality = 0; | |
18 | 16 | Type = ""; |
19 | 17 | Name = ""; |
20 | 18 | Default = false; |
... | ... | @@ -30,15 +28,7 @@ public class ParentList |
30 | 28 | { |
31 | 29 | ID = id; |
32 | 30 | } |
33 | - | |
34 | - public int getCurrentQuality() | |
35 | - { | |
36 | - return currentQuality; | |
37 | - } | |
38 | - public void setCurrentQuality(int q) | |
39 | - { | |
40 | - currentQuality = q; | |
41 | - } | |
31 | + | |
42 | 32 | |
43 | 33 | public boolean getDefault() |
44 | 34 | { | ... | ... |
src/com/upc/pbe/upcnews/VideoActivity.java
... | ... | @@ -19,6 +19,7 @@ public class VideoActivity extends Activity { |
19 | 19 | private final static String TAG = "VideoActivity"; |
20 | 20 | private VideoView video; |
21 | 21 | private HLS h = null; |
22 | + private String filePath; | |
22 | 23 | |
23 | 24 | |
24 | 25 | @Override |
... | ... | @@ -34,20 +35,25 @@ public class VideoActivity extends Activity { |
34 | 35 | } |
35 | 36 | |
36 | 37 | setContentView(R.layout.activity_video); |
38 | + filePath = ((UpcApp)getApplication()).getLocalPath() + "video.ts"; | |
37 | 39 | video = (VideoView) findViewById(R.id.VideoView1); |
38 | 40 | //Creem un listener associat al fi de l'activitat (el fi de cada ts) |
39 | 41 | io.vov.vitamio.widget.MediaController mc = new MediaController(this); |
40 | 42 | video.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { |
41 | 43 | public void onCompletion(MediaPlayer mp) { |
42 | 44 | //Al acabar cada ts, reproduit el seguent |
43 | - playNext(); | |
45 | + if(h.hasEnded()) | |
46 | + { | |
47 | + finish(); | |
48 | + return; | |
49 | + } | |
50 | + h.buffer(); | |
44 | 51 | } |
45 | 52 | }); |
46 | 53 | mc.setOnFFLeftListener(new View.OnClickListener() { |
47 | 54 | public void onClick(View v) { |
48 | 55 | Log.d(TAG, "FFLEFT"); |
49 | - video.stopPlayback(); | |
50 | - playPrevious(); | |
56 | + video.seekTo(-100); | |
51 | 57 | } |
52 | 58 | }); |
53 | 59 | mc.setOnFFRightListener(new View.OnClickListener() { |
... | ... | @@ -60,39 +66,29 @@ public class VideoActivity extends Activity { |
60 | 66 | video.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH); |
61 | 67 | //Creem un gestor HLS, carreguem el video i iniciem la reproduccio |
62 | 68 | h = ((UpcApp)getApplication()).getHLS(); |
63 | - h.startDownloadManager(this); | |
69 | + h.setVideoViewer(video); | |
70 | + h.setVideoActivity(this); | |
64 | 71 | h.loadVideo(); |
65 | 72 | video.stopPlayback(); |
66 | 73 | video.setMediaController(mc); |
67 | - playNext(); | |
68 | - } | |
69 | - | |
70 | - public void play(String url) { | |
71 | - if(url == null) { | |
72 | - super.finish(); | |
73 | - return; | |
74 | - } | |
75 | - Log.d(TAG,"A reproduir: " + url); | |
76 | - video.setVideoPath("file://" + url); | |
77 | - video.start(); | |
78 | - video.requestFocus(); | |
74 | + video.setVideoPath("file://" + filePath); | |
75 | + h.downloadSegment(playNext()); | |
79 | 76 | } |
80 | 77 | |
81 | - public void playNext() { | |
78 | + public String playNext() { | |
82 | 79 | try { |
83 | - String next = h.next(); | |
84 | - play(next); | |
80 | + return h.next(); | |
85 | 81 | } |
86 | 82 | catch(IOException e) { |
87 | 83 | Toast.makeText(this, "No s'ha trobat el segment", Toast.LENGTH_LONG).show(); |
88 | 84 | super.finish(); |
89 | - return; | |
85 | + return ""; | |
90 | 86 | } |
91 | 87 | } |
92 | 88 | public void playPrevious() { |
93 | 89 | try { |
94 | 90 | String prev = h.previous(); |
95 | - play(prev); | |
91 | + //play(prev); | |
96 | 92 | } |
97 | 93 | catch(IOException e) { |
98 | 94 | Toast.makeText(this, "No s'ha trobat el segment", Toast.LENGTH_LONG).show(); |
... | ... | @@ -107,4 +103,5 @@ public class VideoActivity extends Activity { |
107 | 103 | video.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0); |
108 | 104 | super.onConfigurationChanged(newConfig); |
109 | 105 | } |
106 | + | |
110 | 107 | } |
111 | 108 | \ No newline at end of file | ... | ... |